Как предоставить пользовательский класс Application для моего теста Espresso Activity?
Я довольно новичок в эспрессо, но я пытаюсь протестировать относительно простую активность. У моего приложения для Android есть собственный класс приложений. Как я могу сказать Espresso использовать поддельную (или пользовательскую) версию этого класса?
Вот моя пользовательская версия Приложения. Это создает некоторые тестовые данные (отредактировано здесь для краткости). В будущем я также переопределю некоторые методы.
public class MockMyApplication extends MyApplication {
@Override
public void onCreate() {
super.onCreate();
// create some location data for testing
DataRecord rec = new DataRecord(1);
rec.setName("TestLoc1");
rec.setDescription("an important customer");
MyData.add(rec);
}
}
Моя попытка использовать это выглядит так:
@RunWith(AndroidJUnit4.class)
@LargeTest
public class LocEditActivityTest extends AndroidJUnitRunner {
@Rule
public ActivityTestRule<LocEditActivity> activityTestRule
= new ActivityTestRule<>(LocEditActivity.class);
@Override
public Application newApplication(ClassLoader cl, String className, Context context) throws IllegalAccessException, ClassNotFoundException, InstantiationException {
return super.newApplication(cl, MockMyApplication.class.getName(), context);
}
@Test
public void testActivity_ExistingLoc() {
Intent i = new Intent();
i.putExtra("loc",1);
activityTestRule.launchActivity(i);
onView(withId(R.id.editName)).check(matches(withText("TestLoc1")));
// shutdown
onView(withContentDescription("Navigate up")).perform(click());
}
}
Используя отладчик, я определил, что когда onCreate LocEditAcitivity вызывает getApplication(), он возвращает класс MyApplication с пустыми данными, а не MockedMyApplication с моими тестовыми данными.
1 ответ
Нашел это!
Похоже, я неправильно понял использование класса "Runner". Мне нужно было создать свой собственный Runner, который расширил бы AndroidJUnitRunner:
import android.app.Application;
import android.content.Context;
import android.support.test.runner.AndroidJUnitRunner;
// Our own test runniner - uses MockMyApplication as a mocked app class
public class MyAndroidTestRunner extends AndroidJUnitRunner {
@Override
public Application newApplication(ClassLoader cl, String className, Context context) throws IllegalAccessException, ClassNotFoundException, InstantiationException {
return super.newApplication(cl, MockMyApplication.class.getName(), context);
}
}
А затем в build.gradle (app) запись testInstrumentationRunner должна указывать на нового бегуна:
testInstrumentationRunner "com.winwaed.xyzapp.MyAndroidTestRunner"
Поскольку переопределение newApplication было в неправильном месте, это должно быть удалено из моего тестового класса. Кроме того, тестовый класс больше не расширяет классы. (т.е. я по существу разделил класс бегуна и тестовый класс - как я уже сказал, я неправильно понял класс бегуна)