Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Mock Partially using Dagger
Search
Fumihiko Shiroyama
May 09, 2017
Programming
0
650
Mock Partially using Dagger
How to mock partially using Dagger 2
Fumihiko Shiroyama
May 09, 2017
Tweet
Share
More Decks by Fumihiko Shiroyama
See All by Fumihiko Shiroyama
The world of Android wireless communications without Internet
srym
1
120
AWS Device FarmとCircleCIでAndroidのUIテストを自動化しよう
srym
1
4.9k
Spring BootをKotlinで作成しAmazon Elastic Container Service (ECS) で稼働させる
srym
6
1.9k
iOSDC_2019_DeviceFarm.pdf
srym
8
19k
世界で戦うエンジニアになるために_公開用.pdf
srym
18
45k
Unit Testing in a Nutshell - DroidKaigi 2018
srym
11
15k
Clean Architecture & TDD
srym
1
3.7k
はやい・やすい・うまい!スタートアップでも使える Retrofit + RxJava で瞬間APIクッキングレシピ
srym
2
590
I/O 2017 Short Report
srym
0
300
Other Decks in Programming
See All in Programming
VR HMDとしてのVision Pro+ゲーム開発について
yasei_no_otoko
0
100
Kaigi on Rails 2024 - Rails APIモードのためのシンプルで効果的なCSRF対策 / kaigionrails-2024-csrf
corocn
5
3.4k
デプロイを任されたので、教わった通りにデプロイしたら障害になった件 ~俺のやらかしを越えてゆけ~
techouse
52
32k
Generative AI Use Cases JP (略称:GenU)奮闘記
hideg
0
150
Pinia Colada が実現するスマートな非同期処理
naokihaba
2
160
推し活の ハイトラフィックに立ち向かう Railsとアーキテクチャ - Kaigi on Rails 2024
falcon8823
6
2.2k
go.mod、DockerfileやCI設定に分散しがちなGoのバージョンをまとめて管理する / Go Connect #3
arthur1
10
2.4k
ピラミッド、アイスクリームコーン、SMURF: 自動テストの最適バランスを求めて / Pyramid Ice-Cream-Cone and SMURF
twada
PRO
9
1k
プロジェクト新規参入者のリードタイム短縮の観点から見る、品質の高いコードとアーキテクチャを保つメリット
d_endo
1
1k
ECS Service Connectのこれまでのアップデートと今後のRoadmapを見てみる
tkikuc
2
210
LLM生成文章の精度評価自動化とプロンプトチューニングの効率化について
layerx
PRO
2
140
推し活としてのrails new/oshikatsu_ha_iizo
sakahukamaki
3
1.7k
Featured
See All Featured
Designing for humans not robots
tammielis
249
25k
Rails Girls Zürich Keynote
gr2m
93
13k
Music & Morning Musume
bryan
46
6.1k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
28
9.1k
Unsuck your backbone
ammeep
668
57k
Art, The Web, and Tiny UX
lynnandtonic
296
20k
A Tale of Four Properties
chriscoyier
156
23k
Put a Button on it: Removing Barriers to Going Fast.
kastner
59
3.5k
Producing Creativity
orderedlist
PRO
341
39k
Rebuilding a faster, lazier Slack
samanthasiow
79
8.6k
Code Reviewing Like a Champion
maltzj
519
39k
How STYLIGHT went responsive
nonsquared
95
5.2k
Transcript
Mock Partially @fushiroyama
Android Testing Bootcamp • https://android-testing- bootcamp.connpass.com/ • https://android-testing- bootcamp.connpass.com/event/55274/
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
Normal Way
Application Module @Module public class ApplicationModule { @Provides public Info
providesInfo() { return Info.newInstance(); } @Provides public Auth providesAuth() { return Auth.newInstance(); } }
Application Module @Module public class ApplicationModule { @Provides public Info
providesInfo() { return Info.newInstance(); } @Provides public Auth providesAuth() { return Auth.newInstance(); } }
Application Module @Module public class ApplicationModule { @Provides public Info
providesInfo() { return Info.newInstance(); } @Provides public Auth providesAuth() { return Auth.newInstance(); } }
Application Component @Component(modules = ApplicationModule.class) public interface ApplicationComponent { ActivityComponent
plus(ActivityModule module); void inject(Foo foo); void inject(Bar bar); }
Application Component @Component(modules = ApplicationModule.class) public interface ApplicationComponent { ActivityComponent
plus(ActivityModule module); void inject(Foo foo); void inject(Bar bar); }
Application Component @Component(modules = ApplicationModule.class) public interface ApplicationComponent { ActivityComponent
plus(ActivityModule module); void inject(Foo foo); void inject(Bar bar); }
My Application @Override public void onCreate() { super.onCreate(); applicationComponent =
DaggerApplicationComponent.builder() .applicationModule(new ApplicationModule(this)) .build(); } public ApplicationComponent getApplicationComponent() { return applicationComponent; }
My Application @Override public void onCreate() { super.onCreate(); applicationComponent =
DaggerApplicationComponent.builder() .applicationModule(new ApplicationModule(this)) .build(); } public ApplicationComponent getApplicationComponent() { return applicationComponent; }
My Application @Override public void onCreate() { super.onCreate(); applicationComponent =
DaggerApplicationComponent.builder() .applicationModule(new ApplicationModule(this)) .build(); } public ApplicationComponent getApplicationComponent() { return applicationComponent; }
Partial Mock
Application Module @Module public class ApplicationModule { @Provides public Info
providesInfo() { return Info.newInstance(); } @Provides public Auth providesAuth() { return Auth.newInstance(); } }
Application Module @Module public class ApplicationModule { // removed }
API Module @Module public class ApiModule { @Provides public Info
providesInfo() { return Info.newInstance(); } @Provides public Auth providesAuth() { return Auth.newInstance(); } }
API Module @Module public class ApiModule { @Provides public Info
providesInfo() { return Info.newInstance(); } @Provides public Auth providesAuth() { return Auth.newInstance(); } }
API Module @Module public class ApiModule { @Provides public Info
providesInfo() { return Info.newInstance(); } @Provides public Auth providesAuth() { return Auth.newInstance(); } }
API Component @Component(modules = ApiModule.class) public interface ApiComponent { Info
getInfo(); Auth getAuth(); }
API Component @Component(modules = ApiModule.class) public interface ApiComponent { Info
getInfo(); Auth getAuth(); }
API Component @Component(modules = ApiModule.class) public interface ApiComponent { Info
getInfo(); Auth getAuth(); }
API Component @Component(modules = ApiModule.class) public interface ApiComponent { Info
getInfo(); Auth getAuth(); } /FDFTTBSZ
Component Dependency
Application Component @Component(modules = ApplicationModule.class) public interface ApplicationComponent { ActivityComponent
plus(ActivityModule module); void inject(Foo foo); void inject(Bar bar); }
Application Component @Component(modules = ApplicationModule.class) public interface ApplicationComponent { ActivityComponent
plus(ActivityModule module); void inject(Foo foo); void inject(Bar bar); }
Application Component @Component(modules = ApplicationModule.class, dependencies = ApiComponent.clas) public interface
ApplicationComponent { ActivityComponent plus(ActivityModule module); void inject(Foo foo); void inject(Bar bar); }
Application Component @Component(modules = ApplicationModule.class, dependencies = ApiComponent.clas) public interface
ApplicationComponent { ActivityComponent plus(ActivityModule module); void inject(Foo foo); void inject(Bar bar); }
Custom Application
My Application @Override public void onCreate() { super.onCreate(); applicationComponent =
DaggerApplicationComponent.builder() .applicationModule(new ApplicationModule(this)) .build(); } public ApplicationComponent getApplicationComponent() { return applicationComponent; }
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; }
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; }
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; }
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; }
Mock API Module
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; } }
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; } }
Mock API Component
Mock API Component @Component(modules = MockApiModule.class) public interface MockApiComponent extends
ApiComponent { }
Mock API Component @Component(modules = MockApiModule.class) public interface MockApiComponent extends
ApiComponent { }
Mock API Component @Component(modules = MockApiModule.class) public interface MockApiComponent extends
ApiComponent { }
Test Application
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(); } }
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(); } }
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(); } }
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(); } }
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; } }
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; } }
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; } }
Mock Test Runner
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); } }
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); } }
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); } }
Write Your Test!
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() { } }
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() { } }
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() { } }
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() { } }
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() { } }
Use Your Runner android { defaultConfig { testInstrumentationRunner "your.package.runner.MockTestRunner" }
}
Thank you!