Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
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
AI駆動開発にグラフDBを重ねてみた
satoshi256kbyte
2
780
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
260
GKE で Pod の見方を変えたら、スケールアウト時の挙動を真に捉えられた話
stkk
0
110
まだ間に合う!今年の夏こそSchemeのマクロ展開器を完全理解!
omasanori
0
650
新人はどこまで自力でやり、どこからAIに頼るべきか/エンジニア育成に向き合う_先輩たちの悩みと知見共有会
toppan_digital_dev
1
610
DroidKaigi 2026 「個人開発という実験場: Android エンジニアが手にする4つの自由」
slashnephy
0
230
思考垂れ流し開発 ~音声入力 × AIエージェント × 開発ハーネスによる試行錯誤~
npostring
0
1.1k
世界の中心で、AI(App Intents)をさけぶ ー App Intents中心設計の実践ガイド
touyou
0
390
コンパウンドプロダクト開発のためのローカルプロセスマネージャー再発明 #layerxgo
izumin5210
0
670
Family mrubyの進捗
kishima
1
110
スマート反転とウェブアクセシビリティ
camiha
0
180
【高い買い物LT会】初任給で話題の国産フィジカルAIを買った話
akagami
PRO
0
150
Featured
See All Featured
Between Models and Reality
mayunak
4
450
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
1
900
How STYLIGHT went responsive
nonsquared
100
6.3k
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
310
Practical Orchestrator
shlominoach
191
12k
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
420
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
370
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.8k
Making the Leap to Tech Lead
cromwellryan
135
10k
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.7k
Darren the Foodie - Storyboard
khoart
PRO
3
3.9k
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
350
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(); }