????????JUnit???????趨TestComponent
????Creating a JUnit rule that sets the TestComponent
??????????????β????TestComponent???????Application???У???????????JUnit 4 ?? TestRule
????public class TestComponentRule implements TestRule {
????private final TestComponent mTestComponent;
????private final Context mContext;
????public TestComponentRule(Context context) {
????mContext = context;
????MyApplication application = (MyApplication) context.getApplicationContext();
????mTestComponent = DaggerTestComponent.builder()
????.applicationTestModule(new ApplicationTestModule(application))
????.build();
????}
????public DataManager getMockDataManager() {
????return mTestComponent.dataManager();
????}
????@Override
????public Statement apply(final Statement base?? Description description) {
????return new Statement() {
????@Override
????public void evaluate() throws Throwable {
????MyApplication application = (MyApplication) context.getApplicationContext();
????// Set the TestComponent before the test runs
????application.setComponent(mTestComponent);
????base.evaluate();
????// Clears the component once the tets finishes so it would use the default one.
????application.setComponent(null);
????}
????};
????}
????}
????TestComponentRule??????TestComponent??????????????дapply??????????????μ? Statement???μ?Statement??
????1 ?趨TestComponent??Application???component????
????2????????Statement ??evaluate()????????????test???????У?
????3 ????Application??component???????????????????????????????????????????????????????????
?????????????????????????getMockDataManager()???????????DataManager???????????????????????DataManager??????stub????????????????????????TestApplicationComponent??provideDataManger???????@Singleton?????????Ч?????????б??????????????????????getMockDataManager??????????????????????????????????????????????????stub????
??????д????????
????Writing the tests
??????????????Dagger??????????????TestComponentRule?????????????????????????????????д????????????????? Espresso??дUI?????????????????????????????????????Android??????????д????????????????????app??????????????????????????app????REST API ?м??????????????????RecyclerView???檔???DataManger??????????????????
????public DataManager {
????// Loads usernames from a REST API using a Retrofit
????public Single<List<String>> loadUsernames() {
????return mUsersService.getUsernames();
????}
????}
????loadUsername()???????Retrofit??Rxjava ?????REST API ????????????????Single ????????????????????? ???????????Activity???????usernames??RecyclerView???棬??????????Activity????UsernamesActivity??????????MVP??????????????presenter?????????????????presenter??????
?????????????????????????? Activity????????????????????:
????1???API?????????Ч????????б???????????????????б????檔
????2 ???API??????????????????????“????б?”
????3 ???API ???????????????????“????????????”
???????????????????????
????@Test
????public void usernamesDisplay() {
????// Stub the DataManager with a list of three usernames
????List<String> expectedUsernames = Arrays.asList("Joe"?? "Jemma"?? "Matt");
????when(component.getMockDataManager().loadUsernames())
????.thenReturn(Single.just(expectedUsernames));
????// Start the Activity
????main.launchActivity(null);
????// Check that the three usernames are displayed
????for (Sting username:expectedUsernames) {
????onView(withText(username))
????.check(matches(isDisplayed()));
????}
????}
????@Test
????public void emptyMessageDisplays() {
????// Stub an empty list
????when(component.getMockDataManager().loadUsernames())
????.thenReturn(Single.just(Collections.emptyList()));
????// Start the Activity
????main.launchActivity(null);
????// Check the empty list message displays
????onView(withText("Empty list"))
????.check(matches(isDisplayed()));
????}
????@Test
????public void errorMessageDisplays() {
????// Stub with a Single that emits and error
????when(component.getMockDataManager().loadUsernames())
????.thenReturn(Single.error(new RuntimeException()));
????// Start the Activity
????main.launchActivity(null);
????// Check the error message displays
????onView(withText("Error loading usernames"))
????.check(matches(isDisplayed()));
????}
????}
??????????????????????TestComponentRule ??android ?????????????ActivityTestRule??ActivityTestRule?????????????????UsernamesActivity ???????????? RuleChain ????? TestComponentRule??????ActivityTestRule????С?????????TestComponent???κ?Activity????????Application?????趨?á?
??????????????????????????????????????????
????1 ???when (xxx).thenReturn(yyy)????????????????????stub loadUsernames()????????????磬??????????????????????????Ч????????б??
????2 ???main.launchActivity(null)????activity??
????3 ???check(matches(isDisplayed()));?????????????????????????????????????
????????????????Ч????????????????????????????????????????application????????е???????????????mock????д????????????????????????????????Ч??????????API??????????????????
?????????????????????????????????????????????github?????ribot Android boilerplate ???? ribot app.
?????????????????????Щ覴á??????????test??????stub??÷???????????????????????????????????5-10??stub?????Щstub????????setup()??????????????????????????????????stub?????????????UI????????????????????????ζ??????????DataManager??????????????stub??
????????????????????ribot ??????????????????UI??????????????????з???????к????????磬??????????Android???????250??UI?????????????????????г???????????380??Model???Presenter??????????