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
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.3k
retty-tech-cafe-8
yuyakaido
0
200
mti-eureka-tech-beer
yuyakaido
0
510
Other Decks in Programming
See All in Programming
なぜ型を書くのか? TSKaigi2026で改めて考える #tskaigi_smarthr
kajitack
0
390
使用 Meilisearch 建立新聞搜尋工具
johnroyer
0
160
yield再入門 #phpcon
o0h
PRO
0
630
分散システム、なんですぐ死んでしまうん?耐障害性を高めたいあなたのためのレジリエンスパターン入門
mshibuya
7
6.5k
Claude Opus 4.6以後の受託開発エンジニアの変化(Claude Code開発ノウハウ大公開スペシャルbyクラスメソッド)
iidatakuma
1
810
act2-costs.pdf
sumedhbala
0
120
Built Our Own Background Agent at LayerX #aidevex_findy
layerx
PRO
3
1.4k
AI 輔助遺留系統現代化的經驗分享
jame2408
1
1.2k
ローカルLLMでどこまでコードが書けるか -縮小版 / How much code can be written on a local LLM Shortened
kishida
2
190
気圧・高度・GPSを記録&可視化するアプリ「Koudo」を作った話
hjmkth
1
360
『コードを書く以外の』エンジニアリング〜課金基盤移行プロジェクト推進のためのTips4選
yuriko1211
0
520
アルゴリズムは何を圧縮しているのか ─ Haskell から育った「圧縮代数」というメンタルモデル
naoya
16
3.5k
Featured
See All Featured
Being A Developer After 40
akosma
91
590k
The Spectacular Lies of Maps
axbom
PRO
1
860
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
1
3.7k
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
750
Into the Great Unknown - MozCon
thekraken
41
2.6k
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
64
56k
Agile that works and the tools we love
rasmusluckow
331
22k
Marketing to machines
jonoalderson
1
5.6k
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
390
Raft: Consensus for Rubyists
vanstee
141
7.6k
Ruling the World: When Life Gets Gamed
codingconduct
0
280
Designing Experiences People Love
moore
143
24k
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(); }