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.4k
retty-tech-cafe-8
yuyakaido
0
210
mti-eureka-tech-beer
yuyakaido
0
510
Other Decks in Programming
See All in Programming
生成AI導入の「期待外れ」を乗り越える ー 開発フロー改革が目指す、真の組織変革
starfish719
0
4.9k
「寝てても仕事が進む」Claude Codeで組む第二の脳
tomoyafujita2016
0
340
How I Won Prize Money at a Hackathon Using Codex and Symphony Alpha
yasei_no_otoko
0
110
30年振りにコンパイラの定数整数除算を改善した
herumi
1
210
レビュー履歴をAIに食わせて、 Compose移行を加速するs
shihochan
0
150
属人化した知識を、 AIが辿れる地図にする
pkshadeck
PRO
1
200
AI Engineeringは、AIプロダクトだけのものか? 〜AIがソフトウェアを作る時代の新しい当たり前〜 / No AI in your product. AI Engineering in your development.
rkaga
4
490
Cloudflare is Agents
chimame
0
170
Go 1.27 における memory allocation の高速化
andpad
0
270
AI時代に設計が 最大の生産性レバーになる 意図駆動開発とデータを消さない設計|Don't Delete Your Data or Your Intent — Design as the Deepest Lever in the AI Era
tomohisa
1
1.1k
Pythonの実行はどこまで賢くなったのか? CPythonとPyPyから見る最適化のしくみ
curekoshimizu
0
180
What's New in Android 2026
veronikapj
0
270
Featured
See All Featured
Un-Boring Meetings
codingconduct
0
390
RailsConf 2023
tenderlove
30
1.5k
Design in an AI World
tapps
1
280
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
11k
Building Adaptive Systems
keathley
44
3.2k
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
680
Designing Experiences People Love
moore
143
24k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.9k
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
660
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
490
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
660
The SEO Collaboration Effect
kristinabergwall1
1
520
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(); }