Android тесты: тушение модернизации с Mockito
в своем MainActivity
у меня есть метод, называемый getAPI
что возвращает OTBServiceWrapper
. Используется для настройки дооснащения вызова API.
в своем MainActivityTest
файл я пытаюсь заглушить new OTBService().getService()
называем это getApi
метод делает так, что я могу вернуть MockedOTBService
который изменяет клиента на пользовательский, который возвращает json
.
как есть, текущая реализация будет это MockedOTBService
если бы мне пришлось поместить лесоруба в MockedOTBService
но также падает через и вызывает реальный api, который не хочу я хочу в тесте.
я пытаюсь заглушить вызовы API Retrofit с помощью Mockito и return json
. Кажется, я не могу понять, почему заглушка вызывается, но не тушит рассматриваемый метод.
Примечания:
- я использую
ActivityInstrumentationTestCase2
- я запускаю только один тест
- если я добавлю
verify(mockedOTBService, atLeastOnce()).getService();
is говорит, что он никогда не назывался. - если я изменю
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
Поток
MainActivity.onCreate () > OTBService.getService () > OTBServiceWrapper.createSearch(...)
пытается достичь в рамках тестов
MainActivity.onCreate () > MockedOTBService.getService() > OTBServiceWrapper.createSearch(...)
MainActivity.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();
}
}
OTBService.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.java
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
создайте переменную класса и задатчик класса для службы. Он должен быть в области класса, чтобы предотвратить OnCreate
метод вызывается до того, как вы установили службу на то, что вы хотите. Также создайте экземпляр getter, который устанавливает службу, если вы еще этого не сделали.
в тесте перед вызовом getActivity()
установите службу, чтобы быть вашим макетом услуга. (Возможно, подумайте о перемещении этого на объект поддержки).
MainActivity.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();
}
}