Можно ли издеваться над службами Android в рамках модульных тестов?

Я пытаюсь написать модульные тесты для моего приложения для Android, и я хочу высмеять мой класс обслуживания. Я хочу проверить некоторые ошибки поведения в службе, такие как ошибки подключения или файл не найден.

Чтобы упростить мой вопрос, я начал новый проект Android и создал класс 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); } } 

И я создал новый Android Test Project с этим классом устройств:

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

Это возможно?

Да, это возможно, и я думаю, что пример MyServiceMock.java выше также является альтернативой.

Есть несколько насмешливых фреймворков, которые вы можете использовать для этого.

У меня есть некоторый опыт работы с Мокито .

Вы можете просто высмеять класс MyService и указать, что при вызове метода getNewString верните строку «Это новое значение!».

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

Вы также можете использовать метод Mockito.doThrow () для генерирования исключения при вызове метода mock:

 Mockito.doThrow(new RuntimeException()).when(mockedList).clear(); //following throws RuntimeException: mockedList.clear(); 
Intereting Posts
Oauth 2.0 авторизация для LinkedIn в Android Переключение вкладок, не работающих с щелчком вкладок с помощью PagerSlidingTabStrips Android DDMS Не удается запустить статистику сети с помощью эмулятора Android: как сделать файлы игровых активов доступными для чтения с помощью кода c ++ с помощью ndk Используйте карту google на любых устройствах. (Без игры в Google) Проверьте, равны ли два объекта Bundle на Android? Android Thread.sleep () в AsyncTask freeze UI Рекурсивный поиск файлов Различие между действием «Перетаскивание» и действием «Fling» в recyclerview Android 5.1.1 и выше – getRunningAppProcesses () возвращает только мой пакет приложений Android: Как сделать TextView доступным для редактирования? Кнопку Android выбрать и нажать кнопку Динамически добавлять и удалять вкладки в TabLayout (материальный дизайн) android Можете ли вы установить несколько соединений Bluetooth между одними и теми же двумя устройствами в Android? Что касается http://stackoverflow.com/questions/2381560/how-to-group-a-3×3-grid-of-radio-buttons