在unit testing下可以模拟android服务吗?

我想为我的android应用程序编写unit testing,我想嘲笑我的服务类。 我想testing服务中的一些错误行为,例如连接错误或找不到的文件。

为了简化我的问题,我开始了一个新的Android项目,并创build了一个Activity和一个Service类:

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); } } 

我用这个单元类创build了一个新的Androidtesting项目:

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)); } } 

当我运行unit testing时,预置条件和更改buttontesting都很好。 例如,我想要创build一个MyServiceMock并重写MyService.getNewString以返回其他值,并在testing中模拟此对象。

像这样的东西:

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!"; } } 

那可能吗?

Solutions Collecting From Web of "在unit testing下可以模拟android服务吗?"

是的,这是可能的,我想上面的MyServiceMock.java的例子也是一种select。

有几个嘲笑的框架,你可以使用这个。

我有一些Mockito的经验。

你可以模拟MyService类,并指定当调用getNewString方法时,返回一个string“This is the new value!”。

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

当调用模拟方法时,您也可以使用Mockito.doThrow()方法来引发exception:

 Mockito.doThrow(new RuntimeException()).when(mockedList).clear(); //following throws RuntimeException: mockedList.clear();