Testing Repositories
This commit is contained in:
@@ -1,17 +0,0 @@
|
|||||||
package com.ericampire.android.androidstudycase
|
|
||||||
|
|
||||||
import org.junit.Test
|
|
||||||
|
|
||||||
import org.junit.Assert.*
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Example local unit test, which will execute on the development machine (host).
|
|
||||||
*
|
|
||||||
* See [testing documentation](http://d.android.com/tools/testing).
|
|
||||||
*/
|
|
||||||
class ExampleUnitTest {
|
|
||||||
@Test
|
|
||||||
fun addition_isCorrect() {
|
|
||||||
assertEquals(4, 2 + 2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
package com.ericampire.android.androidstudycase.common
|
||||||
|
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.test.TestCoroutineDispatcher
|
||||||
|
import org.junit.jupiter.api.extension.ExtensionContext
|
||||||
|
import org.junit.jupiter.api.extension.ParameterContext
|
||||||
|
import org.junit.jupiter.api.extension.ParameterResolver
|
||||||
|
|
||||||
|
@ExperimentalCoroutinesApi
|
||||||
|
class CoroutineDispatcherExtension : ParameterResolver {
|
||||||
|
|
||||||
|
override fun supportsParameter(
|
||||||
|
parameterContext: ParameterContext,
|
||||||
|
extensionContext: ExtensionContext?
|
||||||
|
): Boolean {
|
||||||
|
return parameterContext.parameter.type.equals(TestCoroutineDispatcher::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun resolveParameter(
|
||||||
|
parameterContext: ParameterContext?,
|
||||||
|
extensionContext: ExtensionContext?
|
||||||
|
): Any {
|
||||||
|
return TestCoroutineDispatcher()
|
||||||
|
}
|
||||||
|
}
|
||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
package com.ericampire.android.androidstudycase.common
|
||||||
|
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.test.TestCoroutineScope
|
||||||
|
import org.junit.jupiter.api.extension.ExtensionContext
|
||||||
|
import org.junit.jupiter.api.extension.ParameterContext
|
||||||
|
import org.junit.jupiter.api.extension.ParameterResolver
|
||||||
|
|
||||||
|
@ExperimentalCoroutinesApi
|
||||||
|
class CoroutineScopeExtension : ParameterResolver {
|
||||||
|
override fun supportsParameter(
|
||||||
|
parameterContext: ParameterContext,
|
||||||
|
extensionContext: ExtensionContext?
|
||||||
|
): Boolean {
|
||||||
|
return parameterContext.parameter.type.equals(TestCoroutineScope::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun resolveParameter(
|
||||||
|
parameterContext: ParameterContext?,
|
||||||
|
extensionContext: ExtensionContext?
|
||||||
|
): Any {
|
||||||
|
return TestCoroutineScope()
|
||||||
|
}
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
package com.ericampire.android.androidstudycase.common
|
||||||
|
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.test.TestCoroutineDispatcher
|
||||||
|
import kotlinx.coroutines.test.resetMain
|
||||||
|
import kotlinx.coroutines.test.setMain
|
||||||
|
import org.junit.jupiter.api.extension.AfterAllCallback
|
||||||
|
import org.junit.jupiter.api.extension.BeforeAllCallback
|
||||||
|
import org.junit.jupiter.api.extension.ExtensionContext
|
||||||
|
|
||||||
|
@ExperimentalCoroutinesApi
|
||||||
|
class MainCoroutineExtension : BeforeAllCallback, AfterAllCallback {
|
||||||
|
|
||||||
|
private val testDispatcher: TestCoroutineDispatcher = TestCoroutineDispatcher()
|
||||||
|
|
||||||
|
override fun beforeAll(context: ExtensionContext?) {
|
||||||
|
Dispatchers.setMain(testDispatcher)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun afterAll(context: ExtensionContext?) {
|
||||||
|
Dispatchers.resetMain()
|
||||||
|
testDispatcher.cleanupTestCoroutines()
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-2
@@ -61,8 +61,8 @@ class AnimatorRepositoryTest(
|
|||||||
assertEquals(it.data, PreviewData.Animator.data)
|
assertEquals(it.data, PreviewData.Animator.data)
|
||||||
}
|
}
|
||||||
|
|
||||||
coVerify {
|
verify(exactly = 1) { remoteDataSource.findAll() }
|
||||||
remoteDataSource.findAll()
|
coVerify(exactly = PreviewData.Animator.data.size) {
|
||||||
localDataSource.save(any())
|
localDataSource.save(any())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+68
@@ -0,0 +1,68 @@
|
|||||||
|
package com.ericampire.android.androidstudycase.data.repository
|
||||||
|
|
||||||
|
import com.ericampire.android.androidstudycase.common.CoroutineDispatcherExtension
|
||||||
|
import com.ericampire.android.androidstudycase.common.CoroutineScopeExtension
|
||||||
|
import com.ericampire.android.androidstudycase.common.MainCoroutineExtension
|
||||||
|
import com.ericampire.android.androidstudycase.data.datasource.blog.BlogDataSource
|
||||||
|
import com.ericampire.android.androidstudycase.util.PreviewData
|
||||||
|
import com.ericampire.android.androidstudycase.util.Result
|
||||||
|
import com.ericampire.android.androidstudycase.util.data
|
||||||
|
import io.mockk.*
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.flow.collect
|
||||||
|
import kotlinx.coroutines.flow.flowOf
|
||||||
|
import kotlinx.coroutines.test.TestCoroutineDispatcher
|
||||||
|
import kotlinx.coroutines.test.TestCoroutineScope
|
||||||
|
import kotlinx.coroutines.test.runBlockingTest
|
||||||
|
import org.junit.Assert
|
||||||
|
import org.junit.jupiter.api.BeforeEach
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith
|
||||||
|
import kotlin.time.ExperimentalTime
|
||||||
|
|
||||||
|
@ExperimentalCoroutinesApi
|
||||||
|
@ExtendWith(
|
||||||
|
value = [
|
||||||
|
MainCoroutineExtension::class,
|
||||||
|
CoroutineDispatcherExtension::class,
|
||||||
|
CoroutineScopeExtension::class
|
||||||
|
]
|
||||||
|
)
|
||||||
|
class BlogRepositoryTest(
|
||||||
|
private val coroutineScope: TestCoroutineScope,
|
||||||
|
private val dispatcher: TestCoroutineDispatcher
|
||||||
|
) {
|
||||||
|
|
||||||
|
// SUT
|
||||||
|
private lateinit var blogRepository: BlogRepositoryImpl
|
||||||
|
|
||||||
|
// DOC's
|
||||||
|
private val remoteDataSource = mockk<BlogDataSource>(relaxed = true)
|
||||||
|
private val localDataSource = mockk<BlogDataSource>(relaxed = true)
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
fun setup() {
|
||||||
|
blogRepository = BlogRepositoryImpl(
|
||||||
|
remoteDataSource = remoteDataSource,
|
||||||
|
localDataSource = localDataSource,
|
||||||
|
coroutineScope = coroutineScope,
|
||||||
|
coroutineDispatcher = dispatcher
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExperimentalTime
|
||||||
|
@Test
|
||||||
|
fun findingAllStories() = runBlockingTest {
|
||||||
|
every { remoteDataSource.findAll() } returns flowOf(Result.Success(PreviewData.Blog.data))
|
||||||
|
coEvery { localDataSource.save(any()) } just Runs
|
||||||
|
|
||||||
|
blogRepository.findAll().collect {
|
||||||
|
Assert.assertEquals(it.data, PreviewData.Blog.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
verify(exactly = 1) { remoteDataSource.findAll() }
|
||||||
|
coVerify(exactly = PreviewData.Blog.data.size) {
|
||||||
|
localDataSource.save(any())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+100
@@ -0,0 +1,100 @@
|
|||||||
|
package com.ericampire.android.androidstudycase.data.repository
|
||||||
|
|
||||||
|
import com.ericampire.android.androidstudycase.common.CoroutineDispatcherExtension
|
||||||
|
import com.ericampire.android.androidstudycase.common.CoroutineScopeExtension
|
||||||
|
import com.ericampire.android.androidstudycase.common.MainCoroutineExtension
|
||||||
|
import com.ericampire.android.androidstudycase.data.datasource.lottiefiles.LottieFileDataSource
|
||||||
|
import com.ericampire.android.androidstudycase.util.PreviewData
|
||||||
|
import com.ericampire.android.androidstudycase.util.Result
|
||||||
|
import com.ericampire.android.androidstudycase.util.data
|
||||||
|
import io.mockk.*
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.flow.collect
|
||||||
|
import kotlinx.coroutines.flow.flowOf
|
||||||
|
import kotlinx.coroutines.test.TestCoroutineDispatcher
|
||||||
|
import kotlinx.coroutines.test.TestCoroutineScope
|
||||||
|
import kotlinx.coroutines.test.runBlockingTest
|
||||||
|
import org.junit.Assert
|
||||||
|
import org.junit.jupiter.api.BeforeEach
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith
|
||||||
|
import kotlin.time.ExperimentalTime
|
||||||
|
|
||||||
|
@ExperimentalCoroutinesApi
|
||||||
|
@ExtendWith(
|
||||||
|
value = [
|
||||||
|
MainCoroutineExtension::class,
|
||||||
|
CoroutineDispatcherExtension::class,
|
||||||
|
CoroutineScopeExtension::class
|
||||||
|
]
|
||||||
|
)
|
||||||
|
class LottieFileRepositoryTest(
|
||||||
|
private val coroutineScope: TestCoroutineScope,
|
||||||
|
private val dispatcher: TestCoroutineDispatcher
|
||||||
|
) {
|
||||||
|
|
||||||
|
// SUT
|
||||||
|
private lateinit var repository: LottieFileRepositoryImpl
|
||||||
|
|
||||||
|
// DOC's
|
||||||
|
private val remoteDataSource = mockk<LottieFileDataSource>(relaxed = true)
|
||||||
|
private val localDataSource = mockk<LottieFileDataSource>(relaxed = true)
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
fun setup() {
|
||||||
|
repository = LottieFileRepositoryImpl(
|
||||||
|
remoteDataSource = remoteDataSource,
|
||||||
|
localDataSource = localDataSource,
|
||||||
|
coroutineScope = coroutineScope,
|
||||||
|
coroutineDispatcher = dispatcher
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExperimentalTime
|
||||||
|
@Test
|
||||||
|
fun findingFeaturedAnimation() = runBlockingTest {
|
||||||
|
every { remoteDataSource.findFeatured() } returns flowOf(Result.Success(PreviewData.Lottiefile.data))
|
||||||
|
coEvery { localDataSource.save(any()) } just Runs
|
||||||
|
|
||||||
|
repository.findFeatured().collect {
|
||||||
|
Assert.assertEquals(it.data, PreviewData.Lottiefile.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
verify(exactly = 1) { remoteDataSource.findFeatured() }
|
||||||
|
coVerify(exactly = PreviewData.Lottiefile.data.size) {
|
||||||
|
localDataSource.save(any())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExperimentalTime
|
||||||
|
@Test
|
||||||
|
fun findingRecentAnimation() = runBlockingTest {
|
||||||
|
every { remoteDataSource.findRecent() } returns flowOf(Result.Success(PreviewData.Lottiefile.data))
|
||||||
|
coEvery { localDataSource.save(any()) } just Runs
|
||||||
|
|
||||||
|
repository.findRecent().collect {
|
||||||
|
Assert.assertEquals(it.data, PreviewData.Lottiefile.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
verify(exactly = 1) { remoteDataSource.findRecent() }
|
||||||
|
coVerify(exactly = PreviewData.Lottiefile.data.size) {
|
||||||
|
localDataSource.save(any())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExperimentalTime
|
||||||
|
@Test
|
||||||
|
fun findingPopularAnimation() = runBlockingTest {
|
||||||
|
every { remoteDataSource.findPopular() } returns flowOf(Result.Success(PreviewData.Lottiefile.data))
|
||||||
|
coEvery { localDataSource.save(any()) } just Runs
|
||||||
|
|
||||||
|
repository.findPopular().collect {
|
||||||
|
Assert.assertEquals(it.data, PreviewData.Lottiefile.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
verify(exactly = 1) { remoteDataSource.findPopular() }
|
||||||
|
coVerify(exactly = PreviewData.Lottiefile.data.size) {
|
||||||
|
localDataSource.save(any())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+66
@@ -0,0 +1,66 @@
|
|||||||
|
package com.ericampire.android.androidstudycase.data.repository
|
||||||
|
|
||||||
|
import com.ericampire.android.androidstudycase.common.CoroutineDispatcherExtension
|
||||||
|
import com.ericampire.android.androidstudycase.common.CoroutineScopeExtension
|
||||||
|
import com.ericampire.android.androidstudycase.common.MainCoroutineExtension
|
||||||
|
import com.ericampire.android.androidstudycase.data.datasource.user.UserDataSource
|
||||||
|
import com.ericampire.android.androidstudycase.util.PreviewData
|
||||||
|
import com.ericampire.android.androidstudycase.util.Result
|
||||||
|
import com.ericampire.android.androidstudycase.util.data
|
||||||
|
import io.mockk.*
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.flow.collect
|
||||||
|
import kotlinx.coroutines.flow.flowOf
|
||||||
|
import kotlinx.coroutines.test.TestCoroutineDispatcher
|
||||||
|
import kotlinx.coroutines.test.TestCoroutineScope
|
||||||
|
import kotlinx.coroutines.test.runBlockingTest
|
||||||
|
import org.junit.Assert
|
||||||
|
import org.junit.jupiter.api.BeforeEach
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith
|
||||||
|
|
||||||
|
@ExperimentalCoroutinesApi
|
||||||
|
@ExtendWith(
|
||||||
|
value = [
|
||||||
|
MainCoroutineExtension::class,
|
||||||
|
CoroutineDispatcherExtension::class,
|
||||||
|
CoroutineScopeExtension::class
|
||||||
|
]
|
||||||
|
)
|
||||||
|
class UserRepositoryTest(
|
||||||
|
private val coroutineScope: TestCoroutineScope,
|
||||||
|
private val dispatcher: TestCoroutineDispatcher
|
||||||
|
) {
|
||||||
|
// SUT
|
||||||
|
private lateinit var repository: UserRepositoryImpl
|
||||||
|
|
||||||
|
// DOC's
|
||||||
|
private val localDataSource = mockk<UserDataSource>(relaxed = true)
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
fun setup() {
|
||||||
|
repository = UserRepositoryImpl(localDataSource)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun findCurrentUser() = runBlockingTest {
|
||||||
|
every { localDataSource.findAll() } returns flowOf(Result.Success(PreviewData.User.data))
|
||||||
|
|
||||||
|
repository.findAll().collect {
|
||||||
|
Assert.assertEquals(it.data, PreviewData.User.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
verify(exactly = 1) { localDataSource.findAll() }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun saveUser() = runBlockingTest {
|
||||||
|
coEvery { localDataSource.save(PreviewData.User.data.first()) } just Runs
|
||||||
|
|
||||||
|
repository.save(PreviewData.User.data.first())
|
||||||
|
|
||||||
|
coVerify(exactly = 1) {
|
||||||
|
localDataSource.save(PreviewData.User.data.first())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user