Slide 1

Slide 1 text

Mock Partially @fushiroyama

Slide 2

Slide 2 text

Android Testing Bootcamp • https://android-testing- bootcamp.connpass.com/ • https://android-testing- bootcamp.connpass.com/event/55274/

Slide 3

Slide 3 text

TL;DR • Use Dagger2 • Make Partial Component • Use it as Component Dependency • Write Mock Module of that Component • Prepare Test Application class • Specify it in Custom Test Runner

Slide 4

Slide 4 text

Normal Way

Slide 5

Slide 5 text

Application Module @Module public class ApplicationModule { @Provides public Info providesInfo() { return Info.newInstance(); } @Provides public Auth providesAuth() { return Auth.newInstance(); } }

Slide 6

Slide 6 text

Application Module @Module public class ApplicationModule { @Provides public Info providesInfo() { return Info.newInstance(); } @Provides public Auth providesAuth() { return Auth.newInstance(); } }

Slide 7

Slide 7 text

Application Module @Module public class ApplicationModule { @Provides public Info providesInfo() { return Info.newInstance(); } @Provides public Auth providesAuth() { return Auth.newInstance(); } }

Slide 8

Slide 8 text

Application Component @Component(modules = ApplicationModule.class) public interface ApplicationComponent { ActivityComponent plus(ActivityModule module); void inject(Foo foo); void inject(Bar bar); }

Slide 9

Slide 9 text

Application Component @Component(modules = ApplicationModule.class) public interface ApplicationComponent { ActivityComponent plus(ActivityModule module); void inject(Foo foo); void inject(Bar bar); }

Slide 10

Slide 10 text

Application Component @Component(modules = ApplicationModule.class) public interface ApplicationComponent { ActivityComponent plus(ActivityModule module); void inject(Foo foo); void inject(Bar bar); }

Slide 11

Slide 11 text

My Application @Override public void onCreate() { super.onCreate(); applicationComponent = DaggerApplicationComponent.builder() .applicationModule(new ApplicationModule(this)) .build(); } public ApplicationComponent getApplicationComponent() { return applicationComponent; }

Slide 12

Slide 12 text

My Application @Override public void onCreate() { super.onCreate(); applicationComponent = DaggerApplicationComponent.builder() .applicationModule(new ApplicationModule(this)) .build(); } public ApplicationComponent getApplicationComponent() { return applicationComponent; }

Slide 13

Slide 13 text

My Application @Override public void onCreate() { super.onCreate(); applicationComponent = DaggerApplicationComponent.builder() .applicationModule(new ApplicationModule(this)) .build(); } public ApplicationComponent getApplicationComponent() { return applicationComponent; }

Slide 14

Slide 14 text

Partial Mock

Slide 15

Slide 15 text

Application Module @Module public class ApplicationModule { @Provides public Info providesInfo() { return Info.newInstance(); } @Provides public Auth providesAuth() { return Auth.newInstance(); } }

Slide 16

Slide 16 text

Application Module @Module public class ApplicationModule { // removed }

Slide 17

Slide 17 text

API Module @Module public class ApiModule { @Provides public Info providesInfo() { return Info.newInstance(); } @Provides public Auth providesAuth() { return Auth.newInstance(); } }

Slide 18

Slide 18 text

API Module @Module public class ApiModule { @Provides public Info providesInfo() { return Info.newInstance(); } @Provides public Auth providesAuth() { return Auth.newInstance(); } }

Slide 19

Slide 19 text

API Module @Module public class ApiModule { @Provides public Info providesInfo() { return Info.newInstance(); } @Provides public Auth providesAuth() { return Auth.newInstance(); } }

Slide 20

Slide 20 text

API Component @Component(modules = ApiModule.class) public interface ApiComponent { Info getInfo(); Auth getAuth(); }

Slide 21

Slide 21 text

API Component @Component(modules = ApiModule.class) public interface ApiComponent { Info getInfo(); Auth getAuth(); }

Slide 22

Slide 22 text

API Component @Component(modules = ApiModule.class) public interface ApiComponent { Info getInfo(); Auth getAuth(); }

Slide 23

Slide 23 text

API Component @Component(modules = ApiModule.class) public interface ApiComponent { Info getInfo(); Auth getAuth(); } /FDFTTBSZ

Slide 24

Slide 24 text

Component Dependency

Slide 25

Slide 25 text

Application Component @Component(modules = ApplicationModule.class) public interface ApplicationComponent { ActivityComponent plus(ActivityModule module); void inject(Foo foo); void inject(Bar bar); }

Slide 26

Slide 26 text

Application Component @Component(modules = ApplicationModule.class) public interface ApplicationComponent { ActivityComponent plus(ActivityModule module); void inject(Foo foo); void inject(Bar bar); }

Slide 27

Slide 27 text

Application Component @Component(modules = ApplicationModule.class, dependencies = ApiComponent.clas) public interface ApplicationComponent { ActivityComponent plus(ActivityModule module); void inject(Foo foo); void inject(Bar bar); }

Slide 28

Slide 28 text

Application Component @Component(modules = ApplicationModule.class, dependencies = ApiComponent.clas) public interface ApplicationComponent { ActivityComponent plus(ActivityModule module); void inject(Foo foo); void inject(Bar bar); }

Slide 29

Slide 29 text

Custom Application

Slide 30

Slide 30 text

My Application @Override public void onCreate() { super.onCreate(); applicationComponent = DaggerApplicationComponent.builder() .applicationModule(new ApplicationModule(this)) .build(); } public ApplicationComponent getApplicationComponent() { return applicationComponent; }

Slide 31

Slide 31 text

My Application @Override public void onCreate() { super.onCreate(); ApiComponent apiComponent = DaggerApiComponent.builder() .apiModule(new ApiModule()) .build(); applicationComponent = DaggerApplicationComponent.builder() .applicationModule(new ApplicationModule(this)) .apiComponent(apiComponent) .build(); } public ApplicationComponent getApplicationComponent() { return applicationComponent; }

Slide 32

Slide 32 text

My Application @Override public void onCreate() { super.onCreate(); ApiComponent apiComponent = DaggerApiComponent.builder() .apiModule(new ApiModule()) .build(); applicationComponent = DaggerApplicationComponent.builder() .applicationModule(new ApplicationModule(this)) .apiComponent(apiComponent) .build(); } public ApplicationComponent getApplicationComponent() { return applicationComponent; }

Slide 33

Slide 33 text

My Application @Override public void onCreate() { super.onCreate(); ApiComponent apiComponent = DaggerApiComponent.builder() .apiModule(new ApiModule()) .build(); applicationComponent = DaggerApplicationComponent.builder() .applicationModule(new ApplicationModule(this)) .apiComponent(apiComponent) .build(); } public ApplicationComponent getApplicationComponent() { return applicationComponent; }

Slide 34

Slide 34 text

My Application @Override public void onCreate() { super.onCreate(); ApiComponent apiComponent = DaggerApiComponent.builder() .apiModule(new ApiModule()) .build(); applicationComponent = DaggerApplicationComponent.builder() .applicationModule(new ApplicationModule(this)) .apiComponent(apiComponent) .build(); } public ApplicationComponent getApplicationComponent() { return applicationComponent; }

Slide 35

Slide 35 text

Mock API Module

Slide 36

Slide 36 text

Mock API Module @Module public class MockApiModule { private final Auth mockAuthApi; private final Info mockInfoApi; public MockApiModule() { mockAuthApi = Mockito.mock(Auth.class); mockInfoApi = Mockito.mock(Info.class); } @Provides Info providesInfo() { return mockInfoApi; } @Provides public Auth providesAuth() { return mockAuthApi; } }

Slide 37

Slide 37 text

Mock API Module @Module public class MockApiModule { private final Auth mockAuthApi; private final Info mockInfoApi; public MockApiModule() { mockAuthApi = Mockito.mock(Auth.class); mockInfoApi = Mockito.mock(Info.class); } @Provides Info providesInfo() { return mockInfoApi; } @Provides public Auth providesAuth() { return mockAuthApi; } }

Slide 38

Slide 38 text

Mock API Component

Slide 39

Slide 39 text

Mock API Component @Component(modules = MockApiModule.class) public interface MockApiComponent extends ApiComponent { }

Slide 40

Slide 40 text

Mock API Component @Component(modules = MockApiModule.class) public interface MockApiComponent extends ApiComponent { }

Slide 41

Slide 41 text

Mock API Component @Component(modules = MockApiModule.class) public interface MockApiComponent extends ApiComponent { }

Slide 42

Slide 42 text

Test Application

Slide 43

Slide 43 text

Test Application public class TestApplication extends MyApplication { @Override public ApplicationComponent getApplicationComponent() { MockApiComponent mockApiComponent = DaggerMockApiComponent.builder() .mockApiModule(new MockApiModule()) .build(); return DaggerApplicationComponent.builder() .applicationModule(new ApplicationModule(this)) .apiComponent(mockApiComponent) .build(); } }

Slide 44

Slide 44 text

Test Application public class TestApplication extends MyApplication { @Override public ApplicationComponent getApplicationComponent() { MockApiComponent mockApiComponent = DaggerMockApiComponent.builder() .mockApiModule(new MockApiModule()) .build(); return DaggerApplicationComponent.builder() .applicationModule(new ApplicationModule(this)) .apiComponent(mockApiComponent) .build(); } }

Slide 45

Slide 45 text

Test Application public class TestApplication extends MyApplication { @Override public ApplicationComponent getApplicationComponent() { MockApiComponent mockApiComponent = DaggerMockApiComponent.builder() .mockApiModule(new MockApiModule()) .build(); return DaggerApplicationComponent.builder() .applicationModule(new ApplicationModule(this)) .apiComponent(mockApiComponent) .build(); } }

Slide 46

Slide 46 text

Test Application public class TestApplication extends MyApplication { @Override public ApplicationComponent getApplicationComponent() { MockApiComponent mockApiComponent = DaggerMockApiComponent.builder() .mockApiModule(new MockApiModule()) .build(); return DaggerApplicationComponent.builder() .applicationModule(new ApplicationModule(this)) .apiComponent(mockApiComponent) .build(); } }

Slide 47

Slide 47 text

Test Application public class TestApplication extends MyApplication { private MockApiComponent mockApiComponent; @Override public ApplicationComponent getApplicationComponent() { mockApiComponent = DaggerMockApiComponent.builder() .mockApiModule(new MockApiModule()) .build(); return DaggerApplicationComponent.builder() .applicationModule(new ApplicationModule(this)) .apiComponent(mockApiComponent) .build(); } public MockApiComponent getMockApiComponent() { return mockApiComponent; } }

Slide 48

Slide 48 text

Test Application public class TestApplication extends MyApplication { private MockApiComponent mockApiComponent; @Override public ApplicationComponent getApplicationComponent() { mockApiComponent = DaggerMockApiComponent.builder() .mockApiModule(new MockApiModule()) .build(); return DaggerApplicationComponent.builder() .applicationModule(new ApplicationModule(this)) .apiComponent(mockApiComponent) .build(); } public MockApiComponent getMockApiComponent() { return mockApiComponent; } }

Slide 49

Slide 49 text

Test Application public class TestApplication extends MyApplication { private MockApiComponent mockApiComponent; @Override public ApplicationComponent getApplicationComponent() { mockApiComponent = DaggerMockApiComponent.builder() .mockApiModule(new MockApiModule()) .build(); return DaggerApplicationComponent.builder() .applicationModule(new ApplicationModule(this)) .apiComponent(mockApiComponent) .build(); } public MockApiComponent getMockApiComponent() { return mockApiComponent; } }

Slide 50

Slide 50 text

Mock Test Runner

Slide 51

Slide 51 text

Mock Test Runner public class MockTestRunner extends AndroidJUnitRunner { @Override public Application newApplication(ClassLoader cl, String className, Context context) throws InstantiationException, IllegalAccessException, ClassNotFoundException { String testApplicationClassName = TestApplication.class.getCanonicalName(); return super.newApplication(cl, testApplicationClassName, context); } }

Slide 52

Slide 52 text

Mock Test Runner public class MockTestRunner extends AndroidJUnitRunner { @Override public Application newApplication(ClassLoader cl, String className, Context context) throws InstantiationException, IllegalAccessException, ClassNotFoundException { String testApplicationClassName = TestApplication.class.getCanonicalName(); return super.newApplication(cl, testApplicationClassName, context); } }

Slide 53

Slide 53 text

Mock Test Runner public class MockTestRunner extends AndroidJUnitRunner { @Override public Application newApplication(ClassLoader cl, String className, Context context) throws InstantiationException, IllegalAccessException, ClassNotFoundException { String testApplicationClassName = TestApplication.class.getCanonicalName(); return super.newApplication(cl, testApplicationClassName, context); } }

Slide 54

Slide 54 text

Write Your Test!

Slide 55

Slide 55 text

Your Android Test @RunWith(AndroidJUnit4.class) public class YourAndroidTest { @Before public void setUp() throws Exception { TestApplication application = (TestApplication) InstrumentationRegistry.getTargetContext().getApplicationContext(); MockApiComponent mockApiComponent = application.getMockApiComponent(); Info info = mockApiComponent.getInfo(); when(info.access(any())).thenReturn(result); } @Test public void doYourTest() { } }

Slide 56

Slide 56 text

Your Android Test @RunWith(AndroidJUnit4.class) public class YourAndroidTest { @Before public void setUp() throws Exception { TestApplication application = (TestApplication) InstrumentationRegistry.getTargetContext().getApplicationContext(); MockApiComponent mockApiComponent = application.getMockApiComponent(); Info info = mockApiComponent.getInfo(); when(info.access(any())).thenReturn(result); } @Test public void doYourTest() { } }

Slide 57

Slide 57 text

Your Android Test @RunWith(AndroidJUnit4.class) public class YourAndroidTest { @Before public void setUp() throws Exception { TestApplication application = (TestApplication) InstrumentationRegistry.getTargetContext().getApplicationContext(); MockApiComponent mockApiComponent = application.getMockApiComponent(); Info info = mockApiComponent.getInfo(); when(info.access(any())).thenReturn(result); } @Test public void doYourTest() { } }

Slide 58

Slide 58 text

Your Android Test @RunWith(AndroidJUnit4.class) public class YourAndroidTest { @Before public void setUp() throws Exception { TestApplication application = (TestApplication) InstrumentationRegistry.getTargetContext().getApplicationContext(); MockApiComponent mockApiComponent = application.getMockApiComponent(); Info info = mockApiComponent.getInfo(); when(info.access(any())).thenReturn(result); } @Test public void doYourTest() { } }

Slide 59

Slide 59 text

Your Android Test @RunWith(AndroidJUnit4.class) public class YourAndroidTest { @Before public void setUp() throws Exception { TestApplication application = (TestApplication) InstrumentationRegistry.getTargetContext().getApplicationContext(); MockApiComponent mockApiComponent = application.getMockApiComponent(); Info info = mockApiComponent.getInfo(); when(info.access(any())).thenReturn(result); } @Test public void doYourTest() { } }

Slide 60

Slide 60 text

Use Your Runner android { defaultConfig { testInstrumentationRunner "your.package.runner.MockTestRunner" } }

Slide 61

Slide 61 text

Thank you!