2011-09-28 17 views
8

私はAndroidアプリケーション用の単体テストを作成しようとしています。サービスクラスを模擬したいと思います。私は接続エラーやファイルが見つからないなど、サービス内のいくつかのエラー動作をテストしたい。私の質問を簡素化するためにユニットテストでアンドロイドサービスを模擬することは可能ですか?

は、私は新しいのAndroidプロジェクトを開始し、活動およびサービスクラスを作成しました:

MyAndroidProjectActivity.java

package br.org.venturus.android; 

import android.app.Activity; 
import android.content.ComponentName; 
import android.content.Context; 
import android.content.Intent; 
import android.content.ServiceConnection; 
import android.os.Bundle; 
import android.os.IBinder; 
import android.view.View; 
import android.widget.TextView; 
import br.org.venturus.android.service.MyService; 

public class MyAndroidProjectActivity extends Activity { 
    private MyService service; 
    private ServiceConnection mConnection = new ServiceConnection() { 

     public void onServiceConnected(ComponentName className, IBinder binder) { 
      service = ((MyService.MyBinder) binder).getService(); 

     } 

     public void onServiceDisconnected(ComponentName className) { 
      service = null; 
     } 
    }; 
    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     { 
      Intent service = new Intent(this, MyService.class); 
      startService(service); 

      bindService(service, mConnection, Context.BIND_AUTO_CREATE); 
     } 

    } 

    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 
     // stop MyService 
     { 
      Intent svc = new Intent(this, MyService.class); 
      stopService(svc); 
     } 
    } 

    public void doChange(View view) { 
     TextView tv = (TextView) findViewById(R.id.tvHello); 

     tv.setText(service.getNewString()); 
    } 
} 

MyService.java

package br.org.venturus.android.service; 

import br.org.venturus.android.R; 
import android.app.Service; 
import android.content.Intent; 
import android.os.Binder; 
import android.os.IBinder; 

public class MyService extends Service { 

    private IBinder binder; 

    public MyService() { 
     this.binder = new MyBinder(); 
    } 
    @Override 
    public IBinder onBind(Intent intent) { 
     return binder; 
    } 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 

    } 

    public class MyBinder extends Binder { 
     public MyService getService() { 
      return MyService.this; 
     } 
    } 

    public String getNewString() { 
     return getString(R.string.change); 
    } 

} 

私はこのユニットクラスで新しいAndroidテストプロジェクトを作成しましたS:私はユニットテストを実行すると

MyAndroidProjectActivityTest.java

package br.org.venturus.android.test; 

import android.test.ActivityInstrumentationTestCase2; 
import android.test.UiThreadTest; 
import android.widget.Button; 
import android.widget.TextView; 
import br.org.venturus.android.MyAndroidProjectActivity; 
import br.org.venturus.android.R; 

public class MyAndroidProjectActivityTest extends 
     ActivityInstrumentationTestCase2<MyAndroidProjectActivity> { 

    private MyAndroidProjectActivity mActivity; 
    private TextView tvHello; 
    private Button btChange; 

    public MyAndroidProjectActivityTest() { 
     super("br.org.venturus.android", MyAndroidProjectActivity.class); 
    } 

    @Override 
    protected void setUp() throws Exception { 
     super.setUp(); 

     // Get the activity and components 
     { 
      mActivity = this.getActivity(); 
      tvHello = (TextView) mActivity 
        .findViewById(br.org.venturus.android.R.id.tvHello); 
      btChange = (Button) mActivity 
        .findViewById(br.org.venturus.android.R.id.btChange); 
     } 

    } 

    public void testPreconditions() { 
     assertNotNull(tvHello); 
     assertNotNull(btChange); 
    } 

    @UiThreadTest 
    public void testChangeButton() { 
     assertEquals(tvHello.getText(), getActivity().getString(R.string.hello)); 
     btChange.performClick(); 
     assertEquals(tvHello.getText(), getActivity() 
       .getString(R.string.change)); 
    } 
} 

、事前条件および変更ボタンのテストは大丈夫です。たとえば、MyServiceMockを作成し、MyService.getNewStringをオーバーライドして他の値を返し、テストでこのオブジェクトをモックすることです。

このような何か:

MyServiceMock.java

package br.org.venturus.android.test.service; 

import br.org.venturus.android.service.MyService; 

public class MyServiceMock extends MyService { 
    @Override 
    public String getNewString() {  
     return "This is the new value!"; 
    } 
} 

可能ということですか?

答えて

3

はい、可能ですが、上記のMyServiceMock.javaの例も同様です。

これに使用できるいくつかの模擬フレームワークがあります。

私はMockitoでいくつかの経験があります。

MyServiceクラスをモックし、getNewStringメソッドが呼び出されたときに "これが新しい値です!"という文字列を返します。期待を設定

Mockito.doThrow(new RuntimeException()).when(mockedList).clear(); 

//following throws RuntimeException: 
mockedList.clear(); 
+1

は簡単な部分ですが、どのように置き換えるか:あなたはまた、モックメソッドが呼び出された例外をスローするMockito.doThrow()メソッドを使用することができます

MyService myServiceMock = Mockito.mock(MyService.class); Mockito.doReturn("This is the new value!").when(myServiceMock).getNewString(); 

マニフェストで宣言されたサービスは、フレームワークと、作成したモックオブジェクトのすべてのバインディングライフサイクルによって開始されました: 'myServiceMock'? – TWiStErRob

関連する問題