From 8b9aac71aeba4220585f712faccf38d03311581e Mon Sep 17 00:00:00 2001 From: qingmei2 Date: Wed, 24 Jan 2018 00:09:04 +0800 Subject: [PATCH] Add the RxImagePickerProfessor class test code. --- .../core/RxImagePickerProcessor.java | 55 ++++-- .../funtions/FuntionObserverAsConverter.java | 7 +- .../core/RxImagePickerProcessorTest.kt | 168 ++++++++++++++++++ .../rximagepicker/mock/TestImagePicker.kt | 11 +- .../rximagepicker/rule/TestSchedulerRule.kt | 46 +++++ .../org.mockito.plugins.MockMaker | 1 + 6 files changed, 266 insertions(+), 22 deletions(-) create mode 100644 rximagepicker/src/test/java/com/qingmei2/rximagepicker/core/RxImagePickerProcessorTest.kt create mode 100644 rximagepicker/src/test/java/com/qingmei2/rximagepicker/rule/TestSchedulerRule.kt create mode 100644 rximagepicker/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker diff --git a/rximagepicker/src/main/java/com/qingmei2/rximagepicker/core/RxImagePickerProcessor.java b/rximagepicker/src/main/java/com/qingmei2/rximagepicker/core/RxImagePickerProcessor.java index 4135ac0..a3d5201 100644 --- a/rximagepicker/src/main/java/com/qingmei2/rximagepicker/core/RxImagePickerProcessor.java +++ b/rximagepicker/src/main/java/com/qingmei2/rximagepicker/core/RxImagePickerProcessor.java @@ -3,6 +3,7 @@ import android.content.Context; import android.net.Uri; +import android.support.annotation.VisibleForTesting; import com.qingmei2.rximagepicker.config.RxImagePickerConfigProvider; import com.qingmei2.rximagepicker.di.scheduler.IRxImagePickerSchedulers; @@ -20,10 +21,14 @@ public final class RxImagePickerProcessor implements IRxImagePickerProcessor { - private final Context context; - private final ICameraPickerView cameraPickerView; - private final IGalleryPickerView galleryPickerView; - private final IRxImagePickerSchedulers schedulers; + @VisibleForTesting + public final Context context; + @VisibleForTesting + public final ICameraPickerView cameraPickerView; + @VisibleForTesting + public final IGalleryPickerView galleryPickerView; + @VisibleForTesting + public final IRxImagePickerSchedulers schedulers; public RxImagePickerProcessor(Context context, ICameraPickerView cameraPickerView, @@ -38,21 +43,35 @@ public RxImagePickerProcessor(Context context, @Override public Observable process(RxImagePickerConfigProvider configProvider) { return Observable.just(configProvider) - .flatMap(new Function>() { - @Override - public ObservableSource apply(RxImagePickerConfigProvider provider) throws Exception { - switch (provider.getSourcesFrom()) { - case GALLERY: - return galleryPickerView.pickImage(); - case CAMERA: - return cameraPickerView.takePhoto(); - default: - throw new IllegalArgumentException("unknown SourceFrom data."); - } - } - }) - .flatMap(new FuntionObserverAsConverter(configProvider.getObserverAs(), context)) + .flatMap(sourceFrom(cameraPickerView, galleryPickerView)) + .flatMap(observerAs(configProvider, context)) .subscribeOn(schedulers.io()) .observeOn(schedulers.ui()); } + + @VisibleForTesting + public Function> sourceFrom( + ICameraPickerView cameraPickerView, + IGalleryPickerView galleryPickerView) { + return new Function>() { + @Override + public ObservableSource apply(RxImagePickerConfigProvider provider) throws Exception { + switch (provider.getSourcesFrom()) { + case GALLERY: + return galleryPickerView.pickImage(); + case CAMERA: + return cameraPickerView.takePhoto(); + default: + throw new IllegalArgumentException("unknown SourceFrom data."); + } + } + }; + } + + @VisibleForTesting + public Function> observerAs( + RxImagePickerConfigProvider configProvider, + Context context) { + return new FuntionObserverAsConverter(configProvider.getObserverAs(), context); + } } diff --git a/rximagepicker/src/main/java/com/qingmei2/rximagepicker/funtions/FuntionObserverAsConverter.java b/rximagepicker/src/main/java/com/qingmei2/rximagepicker/funtions/FuntionObserverAsConverter.java index eb87810..c8e0177 100644 --- a/rximagepicker/src/main/java/com/qingmei2/rximagepicker/funtions/FuntionObserverAsConverter.java +++ b/rximagepicker/src/main/java/com/qingmei2/rximagepicker/funtions/FuntionObserverAsConverter.java @@ -5,6 +5,7 @@ import android.net.Uri; import android.os.Environment; import android.provider.MediaStore; +import android.support.annotation.VisibleForTesting; import android.util.Log; import com.qingmei2.rximagepicker.config.observeras.ObserverAs; @@ -26,8 +27,10 @@ public final class FuntionObserverAsConverter implements Function + + verify(processor.cameraPickerView, times(1)).takePhoto() + verify(processor.galleryPickerView, never()).pickImage() + observable.test() + .assertComplete() + .assertNoErrors() + .assertValueCount(1) + .assertValueAt(0, mockUri) + } + + @Test + fun sourceFromTestGallery() { + whenever(mockGalleryPickerView.pickImage()).thenReturn(Observable.just(mockUri)) + + val observable = processor.sourceFrom(processor.cameraPickerView, processor.galleryPickerView) + .apply(instanceProvider(SourcesFrom.GALLERY)) as Observable + + verify(processor.cameraPickerView, never()).takePhoto() + verify(processor.galleryPickerView, times(1)).pickImage() + observable.test() + .assertComplete() + .assertNoErrors() + .assertValueCount(1) + .assertValueAt(0, mockUri) + } + + @Test + fun sourceFromTestFailed() { +// val sourceFrom: SourcesFrom = SourcesFrom.valueOf("123") +// val observable = processor.sourceFrom(processor.cameraPickerView, processor.galleryPickerView) +// .apply(instanceProvider(sourceFrom)) as Observable +// +// observable.test() +// .assertNotComplete() +// .assertError(IllegalArgumentException::class.java) +// +// verify(processor.cameraPickerView, never()).takePhoto() +// verify(processor.galleryPickerView, never()).pickImage() + } + + @Test + fun observerAsTest() { + val provider = instanceProvider() + val function = processor.observerAs(provider, processor.context) as FuntionObserverAsConverter + + assertEquals(function.context, processor.context) + assertEquals(function.observerAs, provider.observerAs) + } + + @Test + fun testProcessCameraAndUri() { + val spy = processor.let { spy(it) } + val configProvider = instanceProvider() + + doReturn(testSourceFrom()) + .whenever(spy).sourceFrom(mockCameraPickerView, mockGalleryPickerView) + doReturn(testObserverAsUri()) + .whenever(spy).observerAs(configProvider, mockContext) + + val value: Observable = spy.process(configProvider) as Observable + + TestObserver().apply { + value.subscribe(this) + rxRule.triggerActions() + + assertComplete() + .assertNoErrors() + .assertValueCount(1) + .assertValueAt(0, mockUri2) + } + } + + @Test + fun testProcessGalleryAndBitmap() { + val spy = processor.let { spy(it) } + val configProvider = instanceProvider() + + doReturn(testSourceFrom()) + .whenever(spy).sourceFrom(mockCameraPickerView, mockGalleryPickerView) + doReturn(testObserverAsbBitmap()) + .whenever(spy).observerAs(configProvider, mockContext) + + val value: Observable = spy.process(configProvider) as Observable + + TestObserver().apply { + value.subscribe(this) + rxRule.triggerActions() + + assertComplete() + .assertNoErrors() + .assertValueCount(1) + .assertValueAt(0, mockBitmap) + } + } + + private fun instanceProvider(sourcesFrom: SourcesFrom = SourcesFrom.CAMERA, + observerAs: ObserverAs = ObserverAs.URI) + : RxImagePickerConfigProvider { + return RxImagePickerConfigProvider(sourcesFrom, observerAs) + } + + private fun testSourceFrom(): Function> { + return Function { provider -> Observable.just(mockUri) } + } + + private fun testObserverAsUri(): Function> { + return Function { uri -> Observable.just(mockUri2) } + } + + private fun testObserverAsbBitmap(): Function> { + return Function { uri -> Observable.just(mockBitmap) } + } +} \ No newline at end of file diff --git a/rximagepicker/src/test/java/com/qingmei2/rximagepicker/mock/TestImagePicker.kt b/rximagepicker/src/test/java/com/qingmei2/rximagepicker/mock/TestImagePicker.kt index 750dd81..5f6e3db 100644 --- a/rximagepicker/src/test/java/com/qingmei2/rximagepicker/mock/TestImagePicker.kt +++ b/rximagepicker/src/test/java/com/qingmei2/rximagepicker/mock/TestImagePicker.kt @@ -1,13 +1,20 @@ package com.qingmei2.rximagepicker.mock +import android.graphics.Bitmap +import android.net.Uri +import com.qingmei2.rximagepicker.config.observeras.AsBitmap +import com.qingmei2.rximagepicker.config.observeras.AsUri import com.qingmei2.rximagepicker.config.sources.Camera import com.qingmei2.rximagepicker.config.sources.Gallery +import io.reactivex.Observable interface TestImagePicker { @Camera - fun camera() + @AsUri + fun camera(): Observable @Gallery - fun gallery() + @AsBitmap + fun gallery(): Observable } diff --git a/rximagepicker/src/test/java/com/qingmei2/rximagepicker/rule/TestSchedulerRule.kt b/rximagepicker/src/test/java/com/qingmei2/rximagepicker/rule/TestSchedulerRule.kt new file mode 100644 index 0000000..4eabd00 --- /dev/null +++ b/rximagepicker/src/test/java/com/qingmei2/rximagepicker/rule/TestSchedulerRule.kt @@ -0,0 +1,46 @@ +package com.qingmei2.rximagepicker.rule + +import io.reactivex.plugins.RxJavaPlugins +import io.reactivex.schedulers.TestScheduler +import org.junit.rules.TestRule +import org.junit.runner.Description +import org.junit.runners.model.Statement +import java.util.concurrent.TimeUnit + +class TestSchedulerRule : TestRule { + + private var testScheduler: TestScheduler = TestScheduler() + + override fun apply(base: Statement?, description: Description?): Statement { + return object : Statement() { + @Throws(Throwable::class) + override fun evaluate() { + RxJavaPlugins.setIoSchedulerHandler { testScheduler } + RxJavaPlugins.setComputationSchedulerHandler { testScheduler } + RxJavaPlugins.setNewThreadSchedulerHandler { testScheduler } + RxJavaPlugins.setSingleSchedulerHandler { testScheduler } + try { + base?.evaluate() + } finally { + RxJavaPlugins.reset() + } + } + } + } + + fun advanceTimeTo(delayTime: Long, timeUnit: TimeUnit) { + testScheduler.advanceTimeTo(delayTime, timeUnit) + } + + fun advanceTimeBy(delayTime: Long, timeUnit: TimeUnit) { + testScheduler.advanceTimeBy(delayTime, timeUnit) + } + + fun triggerActions() { + testScheduler.triggerActions() + } + + fun getScheduler(): TestScheduler { + return testScheduler + } +} diff --git a/rximagepicker/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/rximagepicker/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 0000000..ca6ee9c --- /dev/null +++ b/rximagepicker/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline \ No newline at end of file