From 3374f11ae685488bd0a51762aaeb403de70919bd Mon Sep 17 00:00:00 2001 From: Shivansh Saini Date: Fri, 22 Mar 2019 16:22:35 +0530 Subject: [PATCH] Test suite for StreamsModel --- build.gradle | 4 +- vlc-android/build.gradle | 9 ++ .../videolan/vlc/util/RoboLiteTestRunner.kt | 32 +++++ .../vlc/viewmodels/StreamsModelTest.kt | 130 ++++++++++++++++++ 4 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 vlc-android/test/org/videolan/vlc/util/RoboLiteTestRunner.kt create mode 100644 vlc-android/test/org/videolan/vlc/viewmodels/StreamsModelTest.kt diff --git a/build.gradle b/build.gradle index 827b70f30..09d8a4e46 100644 --- a/build.gradle +++ b/build.gradle @@ -52,10 +52,12 @@ ext { pagingVersion = '2.1.0' junitVersion = '4.12' mockito = '2.8.9' - powerMock = '1.7.4' retrofit = '2.6.1' moshi = '1.8.0' + powerMock = '2.0.2' espressoVersion = '3.1.1' + livedataTest = '1.1.0' + robolectric = '4.2.1' supportTest = '1.1.0' // versionCode scheme is T M NN RR AA // T: Target/Flavour (1 for Android, 2 for Chrome?) diff --git a/vlc-android/build.gradle b/vlc-android/build.gradle index aaa2c1e7b..17521c8cc 100644 --- a/vlc-android/build.gradle +++ b/vlc-android/build.gradle @@ -292,9 +292,18 @@ dependencies { androidTestImplementation "androidx.arch.core:core-testing:$rootProject.ext.archVersion" androidTestImplementation "androidx.test.ext:junit:$rootProject.ext.supportTest" androidTestUtil "androidx.test:orchestrator:$rootProject.ext.supportTest" + testImplementation "androidx.test:core:$rootProject.ext.supportTest" + testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$rootProject.ext.kotlinx_version" testImplementation "org.mockito:mockito-core:$rootProject.ext.mockito" testImplementation "org.powermock:powermock-api-mockito2:$rootProject.ext.powerMock" testImplementation "org.powermock:powermock-module-junit4:$rootProject.ext.powerMock" +// testImplementation "org.powermock:powermock-module-junit4-rule:$rootProject.ext.powerMock" + testImplementation "org.powermock:powermock-module-junit4-rule-agent:$rootProject.ext.powerMock" + testImplementation "org.powermock:powermock-classloading-xstream:$rootProject.ext.powerMock" + testImplementation "com.jraska.livedata:testing-ktx:$rootProject.ext.livedataTest" + testImplementation "org.robolectric:robolectric:$rootProject.ext.robolectric" + +// unmock 'org.robolectric:android-all:7.1.0_r7-robolectric-0' androidTestImplementation 'androidx.test:rules:1.3.0-alpha01' } diff --git a/vlc-android/test/org/videolan/vlc/util/RoboLiteTestRunner.kt b/vlc-android/test/org/videolan/vlc/util/RoboLiteTestRunner.kt new file mode 100644 index 000000000..1789df2a5 --- /dev/null +++ b/vlc-android/test/org/videolan/vlc/util/RoboLiteTestRunner.kt @@ -0,0 +1,32 @@ +package org.videolan.vlc.util + + +import org.junit.runners.model.FrameworkMethod +import org.junit.runners.model.InitializationError +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config +import org.robolectric.internal.SandboxTestRunner +import org.robolectric.internal.bytecode.Sandbox +import java.lang.reflect.Method + +class RoboLiteTestRunner(cls: Class<*>) : RobolectricTestRunner(cls) { + + override fun beforeTest(sandbox: Sandbox?, method: FrameworkMethod?, bootstrappedMethod: Method?) { + } + + override fun afterTest(method: FrameworkMethod?, bootstrappedMethod: Method?) { + } + + override fun getHelperTestRunner(bootstrappedTestClass: Class<*>?): SandboxTestRunner.HelperTestRunner { + try { + return SandboxTestRunner.HelperTestRunner(bootstrappedTestClass) + } catch (initializationError: InitializationError) { + throw RuntimeException(initializationError) + } + } + + override fun buildGlobalConfig(): Config { + return Config.Builder().setManifest(Config.NONE).build() + } +} + diff --git a/vlc-android/test/org/videolan/vlc/viewmodels/StreamsModelTest.kt b/vlc-android/test/org/videolan/vlc/viewmodels/StreamsModelTest.kt new file mode 100644 index 000000000..518ee90f1 --- /dev/null +++ b/vlc-android/test/org/videolan/vlc/viewmodels/StreamsModelTest.kt @@ -0,0 +1,130 @@ +package org.videolan.vlc.viewmodels + +import android.content.Context +import android.net.Uri +import android.text.TextUtils +import androidx.arch.core.executor.testing.InstantTaskExecutorRule +import androidx.test.core.app.ApplicationProvider +import com.jraska.livedata.test +import junit.framework.TestCase.assertEquals +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.setMain +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.* +import org.powermock.api.mockito.PowerMockito +import org.powermock.core.classloader.annotations.PowerMockIgnore +import org.powermock.core.classloader.annotations.PrepareForTest +import org.powermock.modules.junit4.PowerMockRunner +import org.powermock.modules.junit4.PowerMockRunnerDelegate +import org.robolectric.RobolectricTestRunner +import org.videolan.libvlc.LibVLC +import org.videolan.medialibrary.Medialibrary +import org.videolan.medialibrary.media.MediaWrapper +import org.videolan.vlc.util.RoboLiteTestRunner +import org.videolan.vlc.util.TestUtil +import org.videolan.vlc.util.mock +import java.io.File +import org.mockito.junit.MockitoJUnit +import org.mockito.junit.MockitoRule +import org.powermock.modules.junit4.rule.PowerMockRule +import org.robolectric.annotation.Config + + +//@RunWith(RoboLiteTestRunner::class) +@RunWith(PowerMockRunner::class) +//@PowerMockRunnerDelegate(RobolectricTestRunner::class) +//@Config(sdk=[21]) +@PrepareForTest(value = [Medialibrary::class, LibVLC::class, System::class, Uri::class, TextUtils::class]) +@PowerMockIgnore(value = ["javax.management.*", "org.apache.http.conn.ssl.*", "com.amazonaws.http.conn.ssl.*", "javax.net.ssl.*", "androidx.*"]) +class StreamsModelTest { + + private val mockedLibrary: Medialibrary = PowerMockito.spy(Medialibrary()) + + private val context: Context = mock() + + private lateinit var streamsModel: StreamsModel + +// @Rule +// @JvmField +// val powerMockRule = PowerMockRule() + + @Rule + @JvmField + //To prevent Method getMainLooper in android.os.Looper not mocked error when setting value for MutableLiveData + val instantExecutorRule = InstantTaskExecutorRule() + + @ExperimentalCoroutinesApi + @Before + fun setUp() { + `when`(context.getExternalFilesDir(any())).thenReturn(File("./")) + `when`(context.getDir(any(), anyInt())).thenReturn(File("./")) + + PowerMockito.mockStatic(Medialibrary::class.java) + PowerMockito.mockStatic(System::class.java) + PowerMockito.mockStatic(Uri::class.java) + PowerMockito.mockStatic(TextUtils::class.java) + + PowerMockito.suppress(PowerMockito.method(System::class.java, "loadLibrary", String::class.java)) + PowerMockito.`when`(Medialibrary.getInstance()).thenReturn(mockedLibrary) + + Dispatchers.setMain(Dispatchers.Unconfined) + streamsModel = StreamsModel(context) + } + + @Test + fun failedInitialization_GetEmptyCollection() { + PowerMockito.doReturn(Medialibrary.ML_INIT_FAILED).`when`(mockedLibrary, "nativeInit", any(), any()) + + mockedLibrary.init(context) + + val testResult: MutableList = mutableListOf() + streamsModel.refresh() + streamsModel.dataset + .test() + .awaitValue() + .assertHasValue() + .assertValue(testResult) + } + + @Test + fun addTwoMediaHistory_GetTwoPlayedMediaStreams() { + // Setup + val mockedUri1: Uri = mock() + val mockedUri2: Uri = mock() + + val fakeMediaStrings = TestUtil.createNetworkUris(2) + + `when`(Uri.parse(eq(fakeMediaStrings[0]))).thenReturn(mockedUri1) + `when`(mockedUri1.lastPathSegment).thenReturn(fakeMediaStrings[0]) + `when`(mockedUri1.toString()).thenReturn(fakeMediaStrings[0]) + `when`(Uri.parse(eq(fakeMediaStrings[1]))).thenReturn(mockedUri2) + `when`(mockedUri2.lastPathSegment).thenReturn(fakeMediaStrings[1]) + `when`(mockedUri2.toString()).thenReturn(fakeMediaStrings[1]) + + val fakeMedias = fakeMediaStrings.map { s -> MediaWrapper(Uri.parse(s)) } + val result = fakeMedias.toTypedArray() + + PowerMockito.doReturn(Medialibrary.ML_INIT_SUCCESS).`when`(mockedLibrary, "nativeInit", any(), any()) + PowerMockito.doReturn(result).`when`(mockedLibrary, "nativeLastStreamsPlayed") + + // Execution + mockedLibrary.init(context) + streamsModel.refresh() + + // Assertions + val getResult = streamsModel.dataset + .test() + .awaitValue() + .assertHasValue() + .value() + + assertEquals(2, getResult.size) + assertEquals(result[0], getResult[0]) + assertEquals(result[1], getResult[1]) + } +} \ No newline at end of file