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
android-testing-bootcamp-1
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Yuya Kaido
March 23, 2016
Programming
1.8k
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
android-testing-bootcamp-1
Yuya Kaido
March 23, 2016
More Decks by Yuya Kaido
See All by Yuya Kaido
droidkaigi-2019
yuyakaido
7
4.9k
matching-dev-meetup-1
yuyakaido
1
240
minami-aoyama-night-6
yuyakaido
1
1.3k
eureka-meetup-10
yuyakaido
0
850
droidkaigi-2018
yuyakaido
4
6.2k
navitime-eureka-1
yuyakaido
0
110
droidkaigi-2017
yuyakaido
11
8.4k
retty-tech-cafe-8
yuyakaido
0
210
mti-eureka-tech-beer
yuyakaido
0
510
Other Decks in Programming
See All in Programming
一参加者から『中の人』へ 〜全通PHPerがブースに立って学んだ、カンファレンスを100倍楽しむコツ〜
wp_daisuke
0
110
Discordを用いたラボオートメーション関連情報収集の自動化
noguhiro2002
0
500
異なる設計思想のフレームワークを経験して得た学び
amekuhideki
2
1.5k
Pythonの実行はどこまで賢くなったのか? CPythonとPyPyから見る最適化のしくみ
curekoshimizu
4
2.8k
ソフトウェアラスタライザ
fadis
1
780
「つくるAI」だけではバグは見つからない ~テストに必要な「見つけるAI」を分離させる戦略~
mfunaki
0
230
【デモ】Kiroで体験する仕様駆動開発|設計からコーディングまでAIと進める開発フロー
cmkudo
0
570
[DroidKaigi 2026] Bring your own phones to Gradle Managed Devices
f2lk
0
100
Hello, Hiroshima Geospatial Data! — Exploring DoboX with Python
ra0kley
0
170
Deep dive into the select statement (GopherCon UK)
jespino
0
170
ハーネス設計入門 〜プロンプト、コンテキストの次〜
kinopeee
53
35k
KotlinConf Extended South Korea 2026 Keynote
l2hyunwoo
0
130
Featured
See All Featured
How Software Deployment tools have changed in the past 20 years
geshan
1
34k
The Language of Interfaces
destraynor
162
27k
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
660
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9.2k
Context Engineering - Making Every Token Count
addyosmani
9
1.1k
Discover your Explorer Soul
emna__ayadi
2
1.3k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
870
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
19k
[RailsConf 2023] Rails as a piece of cake
palkan
59
7k
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
710
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.9k
エンジニアに許された特別な時間の終わり
watany
108
250k
Transcript
ςελϒϧͳઃܭΛ ໝͯ͠Έͨ Android Testing Bootcamp #1 yuyakaido
ࣗݾհ • ւ౻༏ʢ͔͍Ͳ͏Ώ͏ʣ • גࣜձࣾΤϨΧ • ςετॻ͚ॻ͚͓͡͞Μ • Android
yuyakaido yuyakaido
גࣜձࣾΤϨΧ • ࣗࣾαʔϏεͷاըɾ։ൃɾӡӦ • ΦϯϥΠϯσʔςΟϯάαʔϏεɿ • Χοϓϧઐ༻ΞϓϦɿ • ࣾһɿ100໊ •
IAC ΤϯδχΞ 60 ඇΤϯδχΞ 40
࣍ • ಈػ • શମํ • શମઃܭ • DaggerͱRxJava •
ςετίʔυ • ·ͱΊ
࣍ • ಈػ • શମํ • શମઃܭ • DaggerͱRxJava •
ςετίʔυ • ·ͱΊ
ಈػ • େنΞϓϦͷϝϯςφϯε͕ਏ͍ • ςετΛॻ͖͍͚ͨͲɺઃܭ͕ͪΌΜͱͯ͠ ͳ͍ͱςετ͕ॻ͖ʹ͍͘ • ςετ͕ॻ͖͍͢ઃܭΛໝͯ͠Έͨ
࣍ • ಈػ • શମํ • શମઃܭ • DaggerͱRxJava •
ςετίʔυ • ·ͱΊ
શମํ • ܧଓతΠϯςάϨʔγϣϯ • ςετͷ࣮ߦΛॏࢹ • ग़དྷΔ͚ͩJUnit/RobolectircͰςετ͢Δ • JUnit/Robolectricͩͱςετ͕͍͠ͱ͜ Ζ͚ͩEspressoͰςετ͢Δ
࣍ • ಈػ • શମํ • શମઃܭ • DaggerͱRxJava •
ςετίʔυ • ·ͱΊ
શମઃܭ Repository UseCase Presenter View Dao Client Database Server
Presentation Domain Infrastructure
Presentation • Ͳ͏දࣔ͢Δ͔Λهड़ • MVPϞυΩ • PresenterPure Java (ContextҎ֎) •
PresenterJUnit/RobolectricͰςετ • ViewEspressoͰςετ(Robolectricซ༻)
Domain • ԿΛ࣮ݱ͢Δ͔Λهड़ • Pure Java (ContextҎ֎) • JUnit/RobolectricͰςετ
Infrastructure • Ͳ͏࣮ͬͯݱ͢Δ͔Λهड़ • DB • API • Pure Java
(ContextҎ֎) • JUnit/RobolectricͰςετ
࣍ • ಈػ • શମํ • શମઃܭ • DaggerͱRxJava •
ςετίʔυ • ·ͱΊ
Dagger • https://github.com/google/dagger • ຊ൪ͱςετͰΠϯελϯεͷࠩ͠ସ͑ PresentationModule DomainModule AppComponent InfraModule
BarModule FooModule BazModule
RxJava • https://github.com/ReactiveX/RxJava • ֤ΛObservableͰ࿈݁ • ࣮ߦ࣌ʹεϨου͕ࣗ༝ʹઃఆग़དྷΔͨΊɺ ςετ͕ॻ͖͘͢ͳΔ
࣍ • ಈػ • શମํ • શମઃܭ • DaggerͱRxJava •
ςετίʔυ • ·ͱΊ
ςετίʔυ • Client • Presenter • ৄͪ͘͜͠Β • https://github.com/yuyakaido/android-genesis
Client • GithubͷAPIΛͬͨαϯϓϧ • ొਓ • GithubClient 㲗 GithubClientTest •
GithubInfraModule 㲗 GithubInfraTestModule
GithubClient public class GithubClient { private GithubService githubService;
@Inject public GithubClient(GithubService service) { this.githubService = service; } public Observable<List<GithubContributor>> getGithubContributors(String owner, String repo) { return CommonClient.retry(githubService.getGithubContributors(owner, repo)); } public Observable<List<GithubContributor>> getGithubContributors() { return getGithubContributors("konifar", "droidkaigi2016"); } public interface GithubService { @GET("/repos/{owner}/{repo}/contributors") Observable<List<GithubContributor>> getGithubContributors( @Path("owner") String owner, @Path("repo") String repo); } } ΞϓϦ
GithubClient public class GithubClient { private GithubService githubService;
@Inject public GithubClient(GithubService service) { this.githubService = service; } public Observable<List<GithubContributor>> getGithubContributors(String owner, String repo) { return CommonClient.retry(githubService.getGithubContributors(owner, repo)); } public Observable<List<GithubContributor>> getGithubContributors() { return getGithubContributors("konifar", "droidkaigi2016"); } public interface GithubService { @GET("/repos/{owner}/{repo}/contributors") Observable<List<GithubContributor>> getGithubContributors( @Path("owner") String owner, @Path("repo") String repo); } } ΞϓϦ
GithubClient public class GithubClient { private GithubService githubService;
@Inject public GithubClient(GithubService service) { this.githubService = service; } public Observable<List<GithubContributor>> getGithubContributors(String owner, String repo) { return CommonClient.retry(githubService.getGithubContributors(owner, repo)); } public Observable<List<GithubContributor>> getGithubContributors() { return getGithubContributors("konifar", "droidkaigi2016"); } public interface GithubService { @GET("/repos/{owner}/{repo}/contributors") Observable<List<GithubContributor>> getGithubContributors( @Path("owner") String owner, @Path("repo") String repo); } } ΞϓϦ
GithubClient public class GithubClient { private GithubService githubService;
@Inject public GithubClient(GithubService service) { this.githubService = service; } public Observable<List<GithubContributor>> getGithubContributors(String owner, String repo) { return CommonClient.retry(githubService.getGithubContributors(owner, repo)); } public Observable<List<GithubContributor>> getGithubContributors() { return getGithubContributors("konifar", "droidkaigi2016"); } public interface GithubService { @GET("/repos/{owner}/{repo}/contributors") Observable<List<GithubContributor>> getGithubContributors( @Path("owner") String owner, @Path("repo") String repo); } } ΞϓϦ
GithubInfraModule @Module public class GithubInfraModule { @Provides @Singleton public
GithubClient.GithubService provideGithubService() { return ApiClientGenerator.generate( GithubClient.GithubService.class, "https://api.github.com"); } } ςετ
GithubClientTest public class GithubClientTest extends InfraTest { @Test public
void getGithubContributorsTest() throws Exception { File file = new File("src/test/assets/json/github_contributors.json"); MockWebServer mockWebServer = new MockWebServer(); mockWebServer.enqueue(ResponseUtil.createMockResponse(file)); mockWebServer.start(); GithubInfraTestModule githubInfraTestModule = new GithubInfraTestModule(); GithubClient githubClient = new GithubClient( githubInfraTestModule.provideGithubService(mockWebServer)); TestSubscriber<List<GithubContributor>> testSubscriber = new TestSubscriber<>(); githubClient.getGithubContributors().subscribe(testSubscriber); testSubscriber.assertNoErrors(); testSubscriber.assertCompleted(); List<GithubContributor> githubContributors = testSubscriber.getOnNextEvents().get(0); assertThat(githubContributors.size(), is(1)); } } ςετ
GithubClientTest public class GithubClientTest extends InfraTest { @Test public
void getGithubContributorsTest() throws Exception { File file = new File("src/test/assets/json/github_contributors.json"); MockWebServer mockWebServer = new MockWebServer(); mockWebServer.enqueue(ResponseUtil.createMockResponse(file)); mockWebServer.start(); GithubInfraTestModule githubInfraTestModule = new GithubInfraTestModule(); GithubClient githubClient = new GithubClient( githubInfraTestModule.provideGithubService(mockWebServer)); TestSubscriber<List<GithubContributor>> testSubscriber = new TestSubscriber<>(); githubClient.getGithubContributors().subscribe(testSubscriber); testSubscriber.assertNoErrors(); testSubscriber.assertCompleted(); List<GithubContributor> githubContributors = testSubscriber.getOnNextEvents().get(0); assertThat(githubContributors.size(), is(1)); } } ςετ
GithubInfraTestModule @Module public class GithubInfraTestModule { @Provides public GithubClient.GithubService
provideGithubService(MockWebServer mockWebServer) { return ApiClientGenerator.generate( GithubClient.GithubService.class, mockWebServer.url("").toString()); } } ςετ
GithubClientTest public class GithubClientTest extends InfraTest { @Test public
void getGithubContributorsTest() throws Exception { File file = new File("src/test/assets/json/github_contributors.json"); MockWebServer mockWebServer = new MockWebServer(); mockWebServer.enqueue(ResponseUtil.createMockResponse(file)); mockWebServer.start(); GithubInfraTestModule githubInfraTestModule = new GithubInfraTestModule(); GithubClient githubClient = new GithubClient( githubInfraTestModule.provideGithubService(mockWebServer)); TestSubscriber<List<GithubContributor>> testSubscriber = new TestSubscriber<>(); githubClient.getGithubContributors().subscribe(testSubscriber); testSubscriber.assertNoErrors(); testSubscriber.assertCompleted(); List<GithubContributor> githubContributors = testSubscriber.getOnNextEvents().get(0); assertThat(githubContributors.size(), is(1)); } } ςετ
GithubClientTest public class GithubClientTest extends InfraTest { @Test public
void getGithubContributorsTest() throws Exception { File file = new File("src/test/assets/json/github_contributors.json"); MockWebServer mockWebServer = new MockWebServer(); mockWebServer.enqueue(ResponseUtil.createMockResponse(file)); mockWebServer.start(); GithubInfraTestModule githubInfraTestModule = new GithubInfraTestModule(); GithubClient githubClient = new GithubClient( githubInfraTestModule.provideGithubService(mockWebServer)); TestSubscriber<List<GithubContributor>> testSubscriber = new TestSubscriber<>(); githubClient.getGithubContributors().subscribe(testSubscriber); testSubscriber.assertNoErrors(); testSubscriber.assertCompleted(); List<GithubContributor> githubContributors = testSubscriber.getOnNextEvents().get(0); assertThat(githubContributors.size(), is(1)); } } ςετ
GithubClientTest public class GithubClientTest extends InfraTest { @Test public
void getGithubContributorsTest() throws Exception { File file = new File("src/test/assets/json/github_contributors.json"); MockWebServer mockWebServer = new MockWebServer(); mockWebServer.enqueue(ResponseUtil.createMockResponse(file)); mockWebServer.start(); GithubInfraTestModule githubInfraTestModule = new GithubInfraTestModule(); GithubClient githubClient = new GithubClient( githubInfraTestModule.provideGithubService(mockWebServer)); TestSubscriber<List<GithubContributor>> testSubscriber = new TestSubscriber<>(); githubClient.getGithubContributors().subscribe(testSubscriber); testSubscriber.assertNoErrors(); testSubscriber.assertCompleted(); List<GithubContributor> githubContributors = testSubscriber.getOnNextEvents().get(0); assertThat(githubContributors.size(), is(1)); } } ςετ
GithubClientTest public class GithubClientTest extends InfraTest { @Test public
void getGithubContributorsTest() throws Exception { File file = new File("src/test/assets/json/github_contributors.json"); MockWebServer mockWebServer = new MockWebServer(); mockWebServer.enqueue(ResponseUtil.createMockResponse(file)); mockWebServer.start(); GithubInfraTestModule githubInfraTestModule = new GithubInfraTestModule(); GithubClient githubClient = new GithubClient( githubInfraTestModule.provideGithubService(mockWebServer)); TestSubscriber<List<GithubContributor>> testSubscriber = new TestSubscriber<>(); githubClient.getGithubContributors().subscribe(testSubscriber); testSubscriber.assertNoErrors(); testSubscriber.assertCompleted(); List<GithubContributor> githubContributors = testSubscriber.getOnNextEvents().get(0); assertThat(githubContributors.size(), is(1)); } } ςετ
GithubClientTest public class GithubClientTest extends InfraTest { @Test public
void getGithubContributorsTest() throws Exception { File file = new File("src/test/assets/json/github_contributors.json"); MockWebServer mockWebServer = new MockWebServer(); mockWebServer.enqueue(ResponseUtil.createMockResponse(file)); mockWebServer.start(); GithubInfraTestModule githubInfraTestModule = new GithubInfraTestModule(); GithubClient githubClient = new GithubClient( githubInfraTestModule.provideGithubService(mockWebServer)); TestSubscriber<List<GithubContributor>> testSubscriber = new TestSubscriber<>(); githubClient.getGithubContributors().subscribe(testSubscriber); testSubscriber.assertNoErrors(); testSubscriber.assertCompleted(); List<GithubContributor> githubContributors = testSubscriber.getOnNextEvents().get(0); assertThat(githubContributors.size(), is(1)); } } ςετ
Clientͷςετ • square/okhttp/mockwebserver͕ศར • DaggerΛͬͯϞοΫαʔόʔͷࠩ͠ସ͑ • JUnit/RobolectricͰߴʹςετՄೳ
Presenter • Clientͱಉ༷ʹGithubͷAPIΛͬͨαϯϓϧ • ొਓ • GithubPresenter 㲗 GithubPresenterTest
GithubPresenter public class GithubPresenter { @Inject Scheduler scheduler;
private GithubView githubView; private GithubUseCase githubUseCase; public GithubPresenter(Context context, GithubView githubView, GithubUseCase githubUseCase) { Genesis.getGenesisComponent(context).inject(this); this.githubView = githubView; this.githubUseCase = githubUseCase; } ʢதུʣ } ΞϓϦ
GithubPresenter public class GithubPresenter { public void onCreate() {
githubView.initViews(); githubView.showProgressBar(); githubView.refresh(); } public void onItemClick(GithubContributor githubContributor) { githubView.startWebViewActivity(githubContributor); } ʢதུʣ } ΞϓϦ
GithubPresenter public class GithubPresenter { public void refresh() {
githubUseCase.getGithubContributors() .subscribeOn(scheduler) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Subscriber<List<GithubContributor>>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { } @Override public void onNext(List<GithubContributor> githubContributors) { githubView.setGithubContributors(githubContributors); githubView.hideProgressBar(); } }); } ʢதུʣ } ΞϓϦ
GithubPresenterTest public class GithubPresenterTest extends PresentationTest { private GithubView
githubView; private GithubUseCase githubUseCase; private GithubPresenter githubPresenter; @Override public void setUp() { super.setUp(); githubView = mock(GithubView.class); githubUseCase = mock(GithubUseCase.class); githubPresenter = new GithubPresenter(getContext(), githubView, githubUseCase); } ʢதུʣ } ςετ
GithubPresenterTest public class GithubPresenter { public void onCreate() {
githubView.initViews(); githubView.showProgressBar(); githubView.refresh(); } } public class GithubPresenterTest extends PresentationTest { @Test public void onCreateTest() { githubPresenter.onCreate(); verify(githubView, times(1)).initViews(); verify(githubView, times(1)).showProgressBar(); verify(githubView, times(1)).refresh(); } } ςετ
GithubPresenterTest public class GithubPresenter { public void onCreate() {
githubView.initViews(); githubView.showProgressBar(); githubView.refresh(); } } public class GithubPresenterTest extends PresentationTest { @Test public void onCreateTest() { githubPresenter.onCreate(); verify(githubView, times(1)).initViews(); verify(githubView, times(1)).showProgressBar(); verify(githubView, times(1)).refresh(); } } ςετ
GithubPresenterTest public class GithubPresenter { public void onCreate() {
githubView.initViews(); githubView.showProgressBar(); githubView.refresh(); } } public class GithubPresenterTest extends PresentationTest { @Test public void onCreateTest() { githubPresenter.onCreate(); verify(githubView, times(1)).initViews(); verify(githubView, times(1)).showProgressBar(); verify(githubView, times(1)).refresh(); } } ςετ
GithubPresenterTest public class GithubPresenter { public void onCreate() {
githubView.initViews(); githubView.showProgressBar(); githubView.refresh(); } } public class GithubPresenterTest extends PresentationTest { @Test public void onCreateTest() { githubPresenter.onCreate(); verify(githubView, times(1)).initViews(); verify(githubView, times(1)).showProgressBar(); verify(githubView, times(1)).refresh(); } } ςετ
GithubPresenterTest public class GithubPresenter { public void onCreate() {
githubView.initViews(); githubView.showProgressBar(); githubView.refresh(); } } public class GithubPresenterTest extends PresentationTest { @Test public void onCreateTest() { githubPresenter.onCreate(); verify(githubView, times(1)).initViews(); verify(githubView, times(1)).showProgressBar(); verify(githubView, times(1)).refresh(); } } ςετ
GithubPresenterTest public class GithubPresenter { public void refresh() { githubUseCase.getGithubContributors()
.subscribeOn(scheduler) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<List<GithubContributor>>() { @Override public void call(List<GithubContributor> githubContributors) { githubView.setGithubContributors(githubContributors); githubView.hideProgressBar(); } }); } } public class GithubPresenterTest extends PresentationTest { @Test public void refreshTest() { Observable<List<GithubContributor>> observable = Observable.create( new Observable.OnSubscribe<List<GithubContributor>>() { @Override public void call(Subscriber<? super List<GithubContributor>> subscriber) { subscriber.onNext(new ArrayList<GithubContributor>()); subscriber.onCompleted(); } } ); when(githubUseCase.getGithubContributors()).thenReturn(observable); githubPresenter.refresh(); verify(githubView, times(1)).setGithubContributors(new ArrayList<GithubContributor>()); verify(githubView, times(1)).hideProgressBar(); } } ςετ
GithubPresenterTest public class GithubPresenter { public void refresh() { githubUseCase.getGithubContributors()
.subscribeOn(scheduler) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<List<GithubContributor>>() { @Override public void call(List<GithubContributor> githubContributors) { githubView.setGithubContributors(githubContributors); githubView.hideProgressBar(); } }); } } public class GithubPresenterTest extends PresentationTest { @Test public void refreshTest() { Observable<List<GithubContributor>> observable = Observable.create( new Observable.OnSubscribe<List<GithubContributor>>() { @Override public void call(Subscriber<? super List<GithubContributor>> subscriber) { subscriber.onNext(new ArrayList<GithubContributor>()); subscriber.onCompleted(); } } ); when(githubUseCase.getGithubContributors()).thenReturn(observable); githubPresenter.refresh(); verify(githubView, times(1)).setGithubContributors(new ArrayList<GithubContributor>()); verify(githubView, times(1)).hideProgressBar(); } } ςετ
GithubPresenterTest public class GithubPresenter { public void refresh() { githubUseCase.getGithubContributors()
.subscribeOn(scheduler) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<List<GithubContributor>>() { @Override public void call(List<GithubContributor> githubContributors) { githubView.setGithubContributors(githubContributors); githubView.hideProgressBar(); } }); } } public class GithubPresenterTest extends PresentationTest { @Test public void refreshTest() { Observable<List<GithubContributor>> observable = Observable.create( new Observable.OnSubscribe<List<GithubContributor>>() { @Override public void call(Subscriber<? super List<GithubContributor>> subscriber) { subscriber.onNext(new ArrayList<GithubContributor>()); subscriber.onCompleted(); } } ); when(githubUseCase.getGithubContributors()).thenReturn(observable); githubPresenter.refresh(); verify(githubView, times(1)).setGithubContributors(new ArrayList<GithubContributor>()); verify(githubView, times(1)).hideProgressBar(); } } ςετ
GithubPresenterTest public class GithubPresenter { public void refresh() { githubUseCase.getGithubContributors()
.subscribeOn(scheduler) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<List<GithubContributor>>() { @Override public void call(List<GithubContributor> githubContributors) { githubView.setGithubContributors(githubContributors); githubView.hideProgressBar(); } }); } } public class GithubPresenterTest extends PresentationTest { @Test public void refreshTest() { Observable<List<GithubContributor>> observable = Observable.create( new Observable.OnSubscribe<List<GithubContributor>>() { @Override public void call(Subscriber<? super List<GithubContributor>> subscriber) { subscriber.onNext(new ArrayList<GithubContributor>()); subscriber.onCompleted(); } } ); when(githubUseCase.getGithubContributors()).thenReturn(observable); githubPresenter.refresh(); verify(githubView, times(1)).setGithubContributors(new ArrayList<GithubContributor>()); verify(githubView, times(1)).hideProgressBar(); } } ςετ
GithubPresenterTest public class GithubPresenter { public void onItemClick(GithubContributor githubContributor)
{ githubView.startWebViewActivity(githubContributor); } } public class GithubPresenterTest extends PresentationTest { @Test public void onItemClickTest() { githubPresenter.onItemClick(null); verify(githubView, times(1)).startWebViewActivity(null); } } ςετ
GithubPresenterTest public class GithubPresenter { public void onItemClick(GithubContributor githubContributor)
{ githubView.startWebViewActivity(githubContributor); } } public class GithubPresenterTest extends PresentationTest { @Test public void onItemClickTest() { githubPresenter.onItemClick(null); verify(githubView, times(1)).startWebViewActivity(null); } } ςετ
GithubPresenterTest public class GithubPresenter { public void onItemClick(GithubContributor githubContributor)
{ githubView.startWebViewActivity(githubContributor); } } public class GithubPresenterTest extends PresentationTest { @Test public void onItemClickTest() { githubPresenter.onItemClick(null); verify(githubView, times(1)).startWebViewActivity(null); } } ςετ
Presenterͷςετ • நԽ͞ΕͨUseCaseͱView • ͦΕΒʹର͢ΔΠϯλϥΫγϣϯ͕దʹߦ ΘΕ͍ͯΔ͔Λςετ • JUnit/RobolectricͰߴʹςετՄೳ
࣍ • ಈػ • શମํ • શମઃܭ • DaggerͱRxJava •
ςετίʔυ • ·ͱΊ
·ͱΊ • PresentationɿͲ͏දࣔ͢Δ͔ • DomainɿԿΛ࣮ݱ͢Δ͔ • InfrastructureɿͲ͏࣮ͬͯݱ͢Δ͔ • DIΛͬͯຊ൪ͱςετͰΠϯελϯεΛΓସ͑Δ •
RxJavaΛ࣮ͬͯߦεϨουͷΓସ͑
·ͱΊ • ϝϦοτ • ֤ͷׂͱґଘؔΛཧͨ͜͠ͱͰςελϒϧͳઃܭʹ • AndroidͷґଘΛ࠷খݶʹͨ͜͠ͱͰߴͳςετՄೳʹ • σϝϦοτ •
Ϋϥε͕ଟ͍ • νʔϜ։ൃͷ߹͋ΔఔͷυΩϡϝϯτ͕ඞਢ
ΤϯδχΞ ઈࢍ࠾༻தʂ ฐࣾ$%0 ʢνʔϑɾυοάɾΦϑΟαʔʣ ͝ਗ਼ௌ ͋Γ͕ͱ͏͍͟͝·ͨ͠ʂ
Thank you :) Credit: NASA Earth Observatory/NOAA NGDC
ิࢿྉ
CommonClient public class CommonClient { private static final int
RETRY_COUNT = 3; private static final int RETRY_DELAY = 3; public static <T> Observable<T> retry(Observable<T> observable) { return observable.retryWhen(new Func1<Observable<? extends Throwable>, Observable<?>>() { @Override public Observable<?> call(Observable<? extends Throwable> observable) { return observable.take(RETRY_COUNT).flatMap(new Func1<Throwable, Observable<?>>() { @Override public Observable<?> call(Throwable throwable) { return Observable.timer(RETRY_DELAY, TimeUnit.SECONDS); } }); } }); } }
ApiClientGenerator public class ApiClientGenerator { public static <T> T
generate(Class<T> clazz, String baseUrl) { return new Retrofit.Builder() .client(HttpClient.getInstance()) .baseUrl(baseUrl) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .build() .create(clazz); } }
HttpClient public class HttpClient { private static OkHttpClient instance;
private HttpClient() {} public static synchronized OkHttpClient getInstance() { if (instance == null) { HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(); httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BASIC); instance = new OkHttpClient.Builder() .addInterceptor(httpLoggingInterceptor) .addNetworkInterceptor(new StethoInterceptor()) .build(); } return instance; } }
GithubView public interface GithubView { void initViews(); void refresh();
void showProgressBar(); void hideProgressBar(); void setGithubContributors(List<GithubContributor> githubContributors); void startWebViewActivity(GithubContributor githubContributor); }
GithubUseCase public interface GithubUseCase { Observable<List<GithubContributor>> getGithubContributors(); }