Тесты андроид: заглушка для Ретрофита с Mockito
В моем MainActivity
есть метод под названием getAPI
, который возвращает OTBServiceWrapper
. Это используется для настройки retrofit для вызова API.
В моем файле MainActivityTest
я пытаюсь заглушить вызов new OTBService().getService()
, который делает метод getApi
, чтобы я мог вернуть MockedOTBService
, который изменяет клиента на пользовательский, который возвращает json
.
Как есть, текущая реализация будет это MockedOTBService
, если я должен был поместить регистратор в MockedOTBService
, но также проваливается и вызывает реальный api, который не хочу я хочу в испытании.
Я пытаюсь заглушить вызовы API Retrofit с помощью Mockito и return json
. Я, кажется, не могу понять, почему заглушка вызывается, но не заглушает метод, о котором идет речь.
Примечания:
- я использую
ActivityInstrumentationTestCase2
- я провожу только один тест
- Если я добавлю
verify(mockedOTBService, atLeastOnce()).getService();
, это говорит, что он никогда не вызывался. - Если я изменяю
when...thenReturn
на использованиеmMainActivity = spy(getActivity())
, то изменения не происходит и вызывается реальный API.
Logcat Вывод
Logger﹕ MockedOTBService was called // Mock is called
Logger﹕ Real OTBService was called // Real API is called
Logger﹕ MainActivity getAPI method class is "$Proxy1" // Mock is shown in MainActivity
Logger﹕ RealAPIResponse JSON Parsed ID: 266 // Real API response returned
Реальный Поток
Основная активность.onCreate () > OTBService.getService () > OTBServiceWrapper.createSearch(...)
Попытка достичь в рамках тестов
Основная активность.onCreate () > MockedOTBService.getService () > OTBServiceWrapper.createSearch(...)
Основная активность.java
public class MainActivity extends Activity {
private OTBServiceWrapper serviceWrapper;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getApi().createSearch(...)
}
public OTBServiceWrapper getApi() {
return new OTBService().getService();
}
}
Отбсервис.java
public class OTBService {
public OTBServiceWrapper getService() {
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(Constants.API_URL)
.build();
return restAdapter.create(OTBServiceWrapper.class);
}
}
OTBServiceWrapper.java
public interface OTBServiceWrapper {
@POST(Constants.API_SEARCHES_POST_URL)
void createSearch(@Body Request request, Callback<Request.Response> callback);
}
MainActivityTest.Ява
public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
private OTBService mMockedOTBService;
private MainActivity mMainActivity;
private View mSearchButton;
public MainActivityTest() { super(MainActivity.class); }
@Override
protected void setUp() throws Exception {
super.setUp();
setActivityInitialTouchMode(true);
System.setProperty("dexmaker.dexcache", getInstrumentation().getTargetContext().getCacheDir().getPath());
mMockedOTBService = mock(OTBService.class);
when(mMockedOTBService.getService()).thenReturn(new MockedOTBService(getInstrumentation().getContext()).getService());
mMainActivity = getActivity();
mSearchButton = mMainActivity.findViewById(R.id.AbSearchButton);
mYourHolidayButton = mMainActivity.findViewById(R.id.AbYourHolidayButton);
}
public void testButtonActions() {
TouchUtils.clickView(this, mSearchButton);
...
}
}
MockedOTBService.java
public class MockedOTBService {
private Context context;
public MockedOTBService(Context context) { this.context = context; }
public OTBServiceWrapper getService() {
RestAdapter restAdapter;
restAdapter = new RestAdapter.Builder()
.setClient(new LocalJsonClient(context))
.setEndpoint(Constants.API_TEST_URL)
.build();
return restAdapter.create(OTBServiceWrapper.class);
}
}
LocalJsonClient.java
@SuppressLint("DefaultLocale")
public class LocalJsonClient implements Client { ... }
Строй.gradle
dependencies {
androidTestCompile 'com.google.dexmaker:dexmaker:1.0'
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.0'
}
1 ответ:
Устраните необходимость издеваться над вашим запросом, разрешив действию установить сервис.
В вашем
MainActivity
Создайте переменную класса и задатчик класса для службы. Это должно быть a в области видимости класса, чтобы предотвратить вызов методаOnCreate
до того, как вы настроите службу на то, что вы хотите, чтобы она была. Кроме того, создайте экземпляр getter, который устанавливает службу, если вы еще не сделали этого.В тесте перед вызовом
getActivity()
Установите сервис в качестве вашего макета сервиса. (Может быть, подумать о перемещение его к объекту поддержки).Основная активность.java
public class MainActivity extends Activity { private static OTBServiceWrapper serviceWrapper; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getServiceWrapper.createSearch(...) } public OTBServiceWrapper getServiceWrapper() { if (serviceWrapper == null) { MainActivity.setServiceWrapper(new OTBService().getService()); } return serviceWrapper; } public static void setServiceWrapper(OTBServiceWrapper serviceWrapper) { MainActivity.serviceWrapper = serviceWrapper; } }
MainActivityTest.java
public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> { private MainActivity mMainActivity; public MainActivityTest() { super(MainActivity.class); } @Override protected void setUp() throws Exception { super.setUp(); setActivityInitialTouchMode(true); MainActivity.setServiceWrapper( new MockedOTBService(getInstrumentation().getContext()).getService() ); mMainActivity = getActivity(); } }