Update core tests to the coroutines tests 1.6.0
This commit is contained in:
parent
b35467fcba
commit
3c80744f6d
13 changed files with 272 additions and 240 deletions
|
|
@ -11,7 +11,7 @@ java {
|
|||
|
||||
compileKotlin {
|
||||
kotlinOptions {
|
||||
freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn"
|
||||
freeCompilerArgs += ['-Xuse-experimental=kotlinx.coroutines.ExperimentalCoroutinesApi']
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -38,4 +38,5 @@ dependencies {
|
|||
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$testing_junit5_version"
|
||||
kaptTest "com.google.dagger:dagger-compiler:$hilt_version"
|
||||
testImplementation "com.squareup.retrofit2:retrofit:$retrofit_version"
|
||||
testImplementation "app.cash.turbine:turbine:$turbine_version"
|
||||
}
|
||||
|
|
@ -1,9 +1,10 @@
|
|||
package org.fnives.test.showcase.core.content
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.test.runBlockingTest
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.fnives.test.showcase.core.storage.content.FavouriteContentLocalStorage
|
||||
import org.fnives.test.showcase.model.content.ContentId
|
||||
import org.junit.jupiter.api.Assertions
|
||||
import org.junit.jupiter.api.Assertions.assertThrows
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
|
|
@ -36,7 +37,7 @@ internal class AddContentToFavouriteUseCaseTest {
|
|||
|
||||
@DisplayName("GIVEN contentId WHEN called THEN storage is called")
|
||||
@Test
|
||||
fun contentIdIsDelegatedToStorage() = runBlockingTest {
|
||||
fun contentIdIsDelegatedToStorage() = runTest {
|
||||
sut.invoke(ContentId("a"))
|
||||
|
||||
verify(mockFavouriteContentLocalStorage, times(1)).markAsFavourite(ContentId("a"))
|
||||
|
|
@ -45,7 +46,7 @@ internal class AddContentToFavouriteUseCaseTest {
|
|||
|
||||
@DisplayName("GIVEN throwing local storage WHEN thrown THEN its propagated")
|
||||
@Test
|
||||
fun storageThrowingIsPropagated() = runBlockingTest {
|
||||
fun storageThrowingIsPropagated() = runTest {
|
||||
whenever(mockFavouriteContentLocalStorage.markAsFavourite(ContentId("a"))).doThrow(
|
||||
RuntimeException()
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package org.fnives.test.showcase.core.content
|
||||
|
||||
import kotlinx.coroutines.test.runBlockingTest
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Disabled
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
|
|
@ -20,27 +20,27 @@ class CodeKataContentRepositoryTest {
|
|||
|
||||
@DisplayName("GIVEN content response WHEN content observed THEN loading AND data is returned")
|
||||
@Test
|
||||
fun happyFlow() = runBlockingTest {
|
||||
fun happyFlow() = runTest {
|
||||
}
|
||||
|
||||
@DisplayName("GIVEN content error WHEN content observed THEN loading AND data is returned")
|
||||
@Test
|
||||
fun errorFlow() = runBlockingTest {
|
||||
fun errorFlow() = runTest {
|
||||
}
|
||||
|
||||
@DisplayName("GIVEN saved cache WHEN collected THEN cache is returned")
|
||||
@Test
|
||||
fun verifyCaching() = runBlockingTest {
|
||||
fun verifyCaching() = runTest {
|
||||
}
|
||||
|
||||
@DisplayName("GIVEN no response from remote source WHEN content observed THEN loading is returned")
|
||||
@Test
|
||||
fun loadingIsShownBeforeTheRequestIsReturned() = runBlockingTest {
|
||||
fun loadingIsShownBeforeTheRequestIsReturned() = runTest {
|
||||
}
|
||||
|
||||
@DisplayName("GIVEN content response THEN error WHEN fetched THEN returned states are loading data loading error")
|
||||
@Test
|
||||
fun whenFetchingRequestIsCalledAgain() = runBlockingTest {
|
||||
fun whenFetchingRequestIsCalledAgain() = runTest {
|
||||
}
|
||||
|
||||
@DisplayName("GIVEN content response THEN error WHEN fetched THEN only 4 items are emitted")
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
package org.fnives.test.showcase.core.content
|
||||
|
||||
import app.cash.turbine.test
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.flow.take
|
||||
import kotlinx.coroutines.flow.toList
|
||||
import kotlinx.coroutines.test.TestCoroutineDispatcher
|
||||
import kotlinx.coroutines.test.runBlockingTest
|
||||
import kotlinx.coroutines.test.UnconfinedTestDispatcher
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.fnives.test.showcase.core.shared.UnexpectedException
|
||||
import org.fnives.test.showcase.model.content.Content
|
||||
import org.fnives.test.showcase.model.content.ContentId
|
||||
|
|
@ -31,12 +32,9 @@ internal class ContentRepositoryTest {
|
|||
|
||||
private lateinit var sut: ContentRepository
|
||||
private lateinit var mockContentRemoteSource: ContentRemoteSource
|
||||
private lateinit var testDispatcher: TestCoroutineDispatcher
|
||||
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
testDispatcher = TestCoroutineDispatcher()
|
||||
testDispatcher.pauseDispatcher()
|
||||
mockContentRemoteSource = mock()
|
||||
sut = ContentRepository(mockContentRemoteSource)
|
||||
}
|
||||
|
|
@ -49,20 +47,13 @@ internal class ContentRepositoryTest {
|
|||
|
||||
@DisplayName("GIVEN content response WHEN content observed THEN loading AND data is returned")
|
||||
@Test
|
||||
fun happyFlow() = runBlockingTest {
|
||||
fun happyFlow() = runTest {
|
||||
val expected = listOf(
|
||||
Resource.Loading(),
|
||||
Resource.Success(listOf(Content(ContentId("a"), "", "", ImageUrl(""))))
|
||||
)
|
||||
whenever(mockContentRemoteSource.get()).doReturn(
|
||||
listOf(
|
||||
Content(
|
||||
ContentId("a"),
|
||||
"",
|
||||
"",
|
||||
ImageUrl("")
|
||||
)
|
||||
)
|
||||
listOf(Content(ContentId("a"), "", "", ImageUrl("")))
|
||||
)
|
||||
|
||||
val actual = sut.contents.take(2).toList()
|
||||
|
|
@ -72,7 +63,7 @@ internal class ContentRepositoryTest {
|
|||
|
||||
@DisplayName("GIVEN content error WHEN content observed THEN loading AND data is returned")
|
||||
@Test
|
||||
fun errorFlow() = runBlockingTest {
|
||||
fun errorFlow() = runTest {
|
||||
val exception = RuntimeException()
|
||||
val expected = listOf(
|
||||
Resource.Loading(),
|
||||
|
|
@ -87,7 +78,7 @@ internal class ContentRepositoryTest {
|
|||
|
||||
@DisplayName("GIVEN saved cache WHEN collected THEN cache is returned")
|
||||
@Test
|
||||
fun verifyCaching() = runBlockingTest {
|
||||
fun verifyCaching() = runTest {
|
||||
val content = Content(ContentId("1"), "", "", ImageUrl(""))
|
||||
val expected = listOf(Resource.Success(listOf(content)))
|
||||
whenever(mockContentRemoteSource.get()).doReturn(listOf(content))
|
||||
|
|
@ -101,7 +92,7 @@ internal class ContentRepositoryTest {
|
|||
|
||||
@DisplayName("GIVEN no response from remote source WHEN content observed THEN loading is returned")
|
||||
@Test
|
||||
fun loadingIsShownBeforeTheRequestIsReturned() = runBlockingTest {
|
||||
fun loadingIsShownBeforeTheRequestIsReturned() = runTest {
|
||||
val expected = Resource.Loading<List<Content>>()
|
||||
val suspendedRequest = CompletableDeferred<Unit>()
|
||||
whenever(mockContentRemoteSource.get()).doSuspendableAnswer {
|
||||
|
|
@ -117,33 +108,32 @@ internal class ContentRepositoryTest {
|
|||
|
||||
@DisplayName("GIVEN content response THEN error WHEN fetched THEN returned states are loading data loading error")
|
||||
@Test
|
||||
fun whenFetchingRequestIsCalledAgain() =
|
||||
runBlockingTest(testDispatcher) {
|
||||
val exception = RuntimeException()
|
||||
val expected = listOf(
|
||||
Resource.Loading(),
|
||||
Resource.Success(emptyList()),
|
||||
Resource.Loading(),
|
||||
Resource.Error<List<Content>>(UnexpectedException(exception))
|
||||
)
|
||||
var first = true
|
||||
whenever(mockContentRemoteSource.get()).doAnswer {
|
||||
if (first) emptyList<Content>().also { first = false } else throw exception
|
||||
}
|
||||
|
||||
val actual = async(testDispatcher) { sut.contents.take(4).toList() }
|
||||
testDispatcher.advanceUntilIdle()
|
||||
sut.fetch()
|
||||
testDispatcher.advanceUntilIdle()
|
||||
|
||||
Assertions.assertEquals(expected, actual.await())
|
||||
fun whenFetchingRequestIsCalledAgain() = runTest(UnconfinedTestDispatcher()) {
|
||||
val exception = RuntimeException()
|
||||
val expected = listOf(
|
||||
Resource.Loading(),
|
||||
Resource.Success(emptyList()),
|
||||
Resource.Loading(),
|
||||
Resource.Error<List<Content>>(UnexpectedException(exception))
|
||||
)
|
||||
var first = true
|
||||
whenever(mockContentRemoteSource.get()).doAnswer {
|
||||
if (first) emptyList<Content>().also { first = false } else throw exception
|
||||
}
|
||||
|
||||
val actual = async {
|
||||
sut.contents.take(4).toList()
|
||||
}
|
||||
sut.fetch()
|
||||
|
||||
Assertions.assertEquals(expected, actual.await())
|
||||
}
|
||||
|
||||
@DisplayName("GIVEN content response THEN error WHEN fetched THEN only 4 items are emitted")
|
||||
@Test
|
||||
fun noAdditionalItemsEmitted() {
|
||||
Assertions.assertThrows(IllegalStateException::class.java) {
|
||||
runBlockingTest(testDispatcher) {
|
||||
runTest(UnconfinedTestDispatcher()) {
|
||||
val exception = RuntimeException()
|
||||
val expected = listOf(
|
||||
Resource.Loading(),
|
||||
|
|
@ -156,13 +146,37 @@ internal class ContentRepositoryTest {
|
|||
if (first) emptyList<Content>().also { first = false } else throw exception
|
||||
}
|
||||
|
||||
val actual = async(testDispatcher) { sut.contents.take(5).toList() }
|
||||
testDispatcher.advanceUntilIdle()
|
||||
val actual = async {
|
||||
sut.contents.take(5).toList()
|
||||
}
|
||||
sut.fetch()
|
||||
testDispatcher.advanceUntilIdle()
|
||||
|
||||
Assertions.assertEquals(expected, actual.await())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("GIVEN content response THEN error WHEN fetched THEN only 4 items are emitted")
|
||||
@Test
|
||||
fun noAdditionalItemsEmittedWithTurbine() = runTest {
|
||||
val exception = RuntimeException()
|
||||
val expected = listOf(
|
||||
Resource.Loading(),
|
||||
Resource.Success(emptyList()),
|
||||
Resource.Loading(),
|
||||
Resource.Error<List<Content>>(UnexpectedException(exception))
|
||||
)
|
||||
var first = true
|
||||
whenever(mockContentRemoteSource.get()).doAnswer {
|
||||
if (first) emptyList<Content>().also { first = false } else throw exception
|
||||
}
|
||||
|
||||
sut.contents.test {
|
||||
sut.fetch()
|
||||
expected.forEach { expectedItem ->
|
||||
Assertions.assertEquals(expectedItem, awaitItem())
|
||||
}
|
||||
Assertions.assertTrue(cancelAndConsumeRemainingEvents().isEmpty())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package org.fnives.test.showcase.core.content
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.test.runBlockingTest
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.jupiter.api.Assertions.assertThrows
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
|
|
@ -34,7 +34,7 @@ internal class FetchContentUseCaseTest {
|
|||
|
||||
@DisplayName("WHEN called THEN repository is called")
|
||||
@Test
|
||||
fun whenCalledRepositoryIsFetched() = runBlockingTest {
|
||||
fun whenCalledRepositoryIsFetched() = runTest {
|
||||
sut.invoke()
|
||||
|
||||
verify(mockContentRepository, times(1)).fetch()
|
||||
|
|
@ -43,7 +43,7 @@ internal class FetchContentUseCaseTest {
|
|||
|
||||
@DisplayName("GIVEN throwing local storage WHEN thrown THEN its thrown")
|
||||
@Test
|
||||
fun whenRepositoryThrowsUseCaseAlsoThrows() = runBlockingTest {
|
||||
fun whenRepositoryThrowsUseCaseAlsoThrows() = runTest {
|
||||
whenever(mockContentRepository.fetch()).doThrow(RuntimeException())
|
||||
|
||||
assertThrows(RuntimeException::class.java) {
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
package org.fnives.test.showcase.core.content
|
||||
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import app.cash.turbine.test
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.take
|
||||
import kotlinx.coroutines.flow.toList
|
||||
import kotlinx.coroutines.test.TestCoroutineDispatcher
|
||||
import kotlinx.coroutines.test.runBlockingTest
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.fnives.test.showcase.core.storage.content.FavouriteContentLocalStorage
|
||||
import org.fnives.test.showcase.model.content.Content
|
||||
import org.fnives.test.showcase.model.content.ContentId
|
||||
|
|
@ -22,7 +22,6 @@ import org.mockito.kotlin.mock
|
|||
import org.mockito.kotlin.whenever
|
||||
|
||||
@Suppress("TestFunctionName")
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
internal class GetAllContentUseCaseTest {
|
||||
|
||||
private lateinit var sut: GetAllContentUseCase
|
||||
|
|
@ -30,11 +29,9 @@ internal class GetAllContentUseCaseTest {
|
|||
private lateinit var mockFavouriteContentLocalStorage: FavouriteContentLocalStorage
|
||||
private lateinit var contentFlow: MutableStateFlow<Resource<List<Content>>>
|
||||
private lateinit var favouriteContentIdFlow: MutableStateFlow<List<ContentId>>
|
||||
private lateinit var testDispatcher: TestCoroutineDispatcher
|
||||
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
testDispatcher = TestCoroutineDispatcher()
|
||||
mockFavouriteContentLocalStorage = mock()
|
||||
mockContentRepository = mock()
|
||||
favouriteContentIdFlow = MutableStateFlow(emptyList())
|
||||
|
|
@ -48,187 +45,168 @@ internal class GetAllContentUseCaseTest {
|
|||
|
||||
@DisplayName("GIVEN loading AND empty favourite WHEN observed THEN loading is shown")
|
||||
@Test
|
||||
fun loadingResourceWithNoFavouritesResultsInLoadingResource() =
|
||||
runBlockingTest(testDispatcher) {
|
||||
favouriteContentIdFlow.value = emptyList()
|
||||
contentFlow.value = Resource.Loading()
|
||||
val expected = Resource.Loading<List<FavouriteContent>>()
|
||||
fun loadingResourceWithNoFavouritesResultsInLoadingResource() = runTest {
|
||||
favouriteContentIdFlow.value = emptyList()
|
||||
contentFlow.value = Resource.Loading()
|
||||
val expected = Resource.Loading<List<FavouriteContent>>()
|
||||
|
||||
val actual = sut.get().take(1).toList()
|
||||
val actual = sut.get().take(1).toList()
|
||||
|
||||
Assertions.assertEquals(listOf(expected), actual)
|
||||
}
|
||||
Assertions.assertEquals(listOf(expected), actual)
|
||||
}
|
||||
|
||||
@DisplayName("GIVEN loading AND listOfFavourite WHEN observed THEN loading is shown")
|
||||
@Test
|
||||
fun loadingResourceWithFavouritesResultsInLoadingResource() =
|
||||
runBlockingTest(testDispatcher) {
|
||||
favouriteContentIdFlow.value = listOf(ContentId("a"))
|
||||
contentFlow.value = Resource.Loading()
|
||||
val expected = Resource.Loading<List<FavouriteContent>>()
|
||||
fun loadingResourceWithFavouritesResultsInLoadingResource() = runTest {
|
||||
favouriteContentIdFlow.value = listOf(ContentId("a"))
|
||||
contentFlow.value = Resource.Loading()
|
||||
val expected = Resource.Loading<List<FavouriteContent>>()
|
||||
|
||||
val actual = sut.get().take(1).toList()
|
||||
val actual = sut.get().take(1).toList()
|
||||
|
||||
Assertions.assertEquals(listOf(expected), actual)
|
||||
}
|
||||
Assertions.assertEquals(listOf(expected), actual)
|
||||
}
|
||||
|
||||
@DisplayName("GIVEN error AND empty favourite WHEN observed THEN error is shown")
|
||||
@Test
|
||||
fun errorResourceWithNoFavouritesResultsInErrorResource() =
|
||||
runBlockingTest(testDispatcher) {
|
||||
favouriteContentIdFlow.value = emptyList()
|
||||
val exception = Throwable()
|
||||
contentFlow.value = Resource.Error(exception)
|
||||
val expected = Resource.Error<List<FavouriteContent>>(exception)
|
||||
fun errorResourceWithNoFavouritesResultsInErrorResource() = runTest {
|
||||
favouriteContentIdFlow.value = emptyList()
|
||||
val exception = Throwable()
|
||||
contentFlow.value = Resource.Error(exception)
|
||||
val expected = Resource.Error<List<FavouriteContent>>(exception)
|
||||
|
||||
val actual = sut.get().take(1).toList()
|
||||
val actual = sut.get().take(1).toList()
|
||||
|
||||
Assertions.assertEquals(listOf(expected), actual)
|
||||
}
|
||||
Assertions.assertEquals(listOf(expected), actual)
|
||||
}
|
||||
|
||||
@DisplayName("GIVEN error AND listOfFavourite WHEN observed THEN error is shown")
|
||||
@Test
|
||||
fun errorResourceWithFavouritesResultsInErrorResource() =
|
||||
runBlockingTest(testDispatcher) {
|
||||
favouriteContentIdFlow.value = listOf(ContentId("b"))
|
||||
val exception = Throwable()
|
||||
contentFlow.value = Resource.Error(exception)
|
||||
val expected = Resource.Error<List<FavouriteContent>>(exception)
|
||||
fun errorResourceWithFavouritesResultsInErrorResource() = runTest {
|
||||
favouriteContentIdFlow.value = listOf(ContentId("b"))
|
||||
val exception = Throwable()
|
||||
contentFlow.value = Resource.Error(exception)
|
||||
val expected = Resource.Error<List<FavouriteContent>>(exception)
|
||||
|
||||
val actual = sut.get().take(1).toList()
|
||||
val actual = sut.get().take(1).toList()
|
||||
|
||||
Assertions.assertEquals(listOf(expected), actual)
|
||||
}
|
||||
Assertions.assertEquals(listOf(expected), actual)
|
||||
}
|
||||
|
||||
@DisplayName("GIVEN listOfContent AND empty favourite WHEN observed THEN favourites are returned")
|
||||
@Test
|
||||
fun successResourceWithNoFavouritesResultsInNoFavouritedItems() =
|
||||
runBlockingTest(testDispatcher) {
|
||||
favouriteContentIdFlow.value = emptyList()
|
||||
val content = Content(ContentId("a"), "b", "c", ImageUrl("d"))
|
||||
contentFlow.value = Resource.Success(listOf(content))
|
||||
val items = listOf(
|
||||
FavouriteContent(content, false)
|
||||
)
|
||||
val expected = Resource.Success(items)
|
||||
fun successResourceWithNoFavouritesResultsInNoFavouritedItems() = runTest {
|
||||
favouriteContentIdFlow.value = emptyList()
|
||||
val content = Content(ContentId("a"), "b", "c", ImageUrl("d"))
|
||||
contentFlow.value = Resource.Success(listOf(content))
|
||||
val items = listOf(
|
||||
FavouriteContent(content, false)
|
||||
)
|
||||
val expected = Resource.Success(items)
|
||||
|
||||
val actual = sut.get().take(1).toList()
|
||||
val actual = sut.get().take(1).toList()
|
||||
|
||||
Assertions.assertEquals(listOf(expected), actual)
|
||||
}
|
||||
Assertions.assertEquals(listOf(expected), actual)
|
||||
}
|
||||
|
||||
@DisplayName("GIVEN listOfContent AND other favourite id WHEN observed THEN favourites are returned")
|
||||
@Test
|
||||
fun successResourceWithDifferentFavouritesResultsInNoFavouritedItems() =
|
||||
runBlockingTest(testDispatcher) {
|
||||
favouriteContentIdFlow.value = listOf(ContentId("x"))
|
||||
val content = Content(ContentId("a"), "b", "c", ImageUrl("d"))
|
||||
contentFlow.value = Resource.Success(listOf(content))
|
||||
val items = listOf(
|
||||
FavouriteContent(content, false)
|
||||
)
|
||||
val expected = Resource.Success(items)
|
||||
fun successResourceWithDifferentFavouritesResultsInNoFavouritedItems() = runTest {
|
||||
favouriteContentIdFlow.value = listOf(ContentId("x"))
|
||||
val content = Content(ContentId("a"), "b", "c", ImageUrl("d"))
|
||||
contentFlow.value = Resource.Success(listOf(content))
|
||||
val items = listOf(
|
||||
FavouriteContent(content, false)
|
||||
)
|
||||
val expected = Resource.Success(items)
|
||||
|
||||
val actual = sut.get().take(1).toList()
|
||||
val actual = sut.get().take(1).toList()
|
||||
|
||||
Assertions.assertEquals(listOf(expected), actual)
|
||||
}
|
||||
Assertions.assertEquals(listOf(expected), actual)
|
||||
}
|
||||
|
||||
@DisplayName("GIVEN listOfContent AND same favourite id WHEN observed THEN favourites are returned")
|
||||
@Test
|
||||
fun successResourceWithSameFavouritesResultsInFavouritedItems() =
|
||||
runBlockingTest(testDispatcher) {
|
||||
favouriteContentIdFlow.value = listOf(ContentId("a"))
|
||||
val content = Content(ContentId("a"), "b", "c", ImageUrl("d"))
|
||||
contentFlow.value = Resource.Success(listOf(content))
|
||||
val items = listOf(
|
||||
FavouriteContent(content, true)
|
||||
)
|
||||
val expected = Resource.Success(items)
|
||||
fun successResourceWithSameFavouritesResultsInFavouritedItems() = runTest {
|
||||
favouriteContentIdFlow.value = listOf(ContentId("a"))
|
||||
val content = Content(ContentId("a"), "b", "c", ImageUrl("d"))
|
||||
contentFlow.value = Resource.Success(listOf(content))
|
||||
val items = listOf(
|
||||
FavouriteContent(content, true)
|
||||
)
|
||||
val expected = Resource.Success(items)
|
||||
|
||||
val actual = sut.get().take(1).toList()
|
||||
val actual = sut.get().take(1).toList()
|
||||
|
||||
Assertions.assertEquals(listOf(expected), actual)
|
||||
}
|
||||
Assertions.assertEquals(listOf(expected), actual)
|
||||
}
|
||||
|
||||
@DisplayName("GIVEN loading then data then added favourite WHEN observed THEN loading then correct favourites are returned")
|
||||
@Test
|
||||
fun whileLoadingAndAddingItemsReactsProperly() =
|
||||
runBlockingTest(testDispatcher) {
|
||||
favouriteContentIdFlow.value = emptyList()
|
||||
val content = Content(ContentId("a"), "b", "c", ImageUrl("d"))
|
||||
contentFlow.value = Resource.Loading()
|
||||
val expected = listOf(
|
||||
Resource.Loading(),
|
||||
Resource.Success(listOf(FavouriteContent(content, false))),
|
||||
Resource.Success(listOf(FavouriteContent(content, true)))
|
||||
)
|
||||
|
||||
val actual = async(testDispatcher) {
|
||||
sut.get().take(3).toList()
|
||||
}
|
||||
testDispatcher.advanceUntilIdle()
|
||||
fun whileLoadingAndAddingItemsReactsProperly() = runTest {
|
||||
favouriteContentIdFlow.value = emptyList()
|
||||
val content = Content(ContentId("a"), "b", "c", ImageUrl("d"))
|
||||
contentFlow.value = Resource.Loading()
|
||||
val expected = listOf(
|
||||
Resource.Loading(),
|
||||
Resource.Success(listOf(FavouriteContent(content, false))),
|
||||
Resource.Success(listOf(FavouriteContent(content, true)))
|
||||
)
|
||||
|
||||
sut.get().test {
|
||||
contentFlow.value = Resource.Success(listOf(content))
|
||||
testDispatcher.advanceUntilIdle()
|
||||
|
||||
favouriteContentIdFlow.value = listOf(ContentId("a"))
|
||||
testDispatcher.advanceUntilIdle()
|
||||
|
||||
Assertions.assertEquals(expected, actual.await())
|
||||
expected.forEach { expectedItem ->
|
||||
Assertions.assertEquals(expectedItem, awaitItem())
|
||||
}
|
||||
Assertions.assertTrue(cancelAndConsumeRemainingEvents().isEmpty())
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("GIVEN loading then data then removed favourite WHEN observed THEN loading then correct favourites are returned")
|
||||
@Test
|
||||
fun whileLoadingAndRemovingItemsReactsProperly() =
|
||||
runBlockingTest(testDispatcher) {
|
||||
favouriteContentIdFlow.value = listOf(ContentId("a"))
|
||||
val content = Content(ContentId("a"), "b", "c", ImageUrl("d"))
|
||||
contentFlow.value = Resource.Loading()
|
||||
val expected = listOf(
|
||||
Resource.Loading(),
|
||||
Resource.Success(listOf(FavouriteContent(content, true))),
|
||||
Resource.Success(listOf(FavouriteContent(content, false)))
|
||||
)
|
||||
|
||||
val actual = async(testDispatcher) {
|
||||
sut.get().take(3).toList()
|
||||
}
|
||||
testDispatcher.advanceUntilIdle()
|
||||
fun whileLoadingAndRemovingItemsReactsProperly() = runTest {
|
||||
favouriteContentIdFlow.value = listOf(ContentId("a"))
|
||||
val content = Content(ContentId("a"), "b", "c", ImageUrl("d"))
|
||||
contentFlow.value = Resource.Loading()
|
||||
val expected = listOf(
|
||||
Resource.Loading(),
|
||||
Resource.Success(listOf(FavouriteContent(content, true))),
|
||||
Resource.Success(listOf(FavouriteContent(content, false)))
|
||||
)
|
||||
|
||||
sut.get().test {
|
||||
contentFlow.value = Resource.Success(listOf(content))
|
||||
testDispatcher.advanceUntilIdle()
|
||||
|
||||
favouriteContentIdFlow.value = emptyList()
|
||||
testDispatcher.advanceUntilIdle()
|
||||
|
||||
Assertions.assertEquals(expected, actual.await())
|
||||
expected.forEach { expectedItem ->
|
||||
Assertions.assertEquals(expectedItem, awaitItem())
|
||||
}
|
||||
Assertions.assertTrue(cancelAndConsumeRemainingEvents().isEmpty())
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("GIVEN loading then data then loading WHEN observed THEN loading then correct favourites then loading are returned")
|
||||
@Test
|
||||
fun loadingThenDataThenLoadingReactsProperly() =
|
||||
runBlockingTest(testDispatcher) {
|
||||
favouriteContentIdFlow.value = listOf(ContentId("a"))
|
||||
val content = Content(ContentId("a"), "b", "c", ImageUrl("d"))
|
||||
contentFlow.value = Resource.Loading()
|
||||
val expected = listOf(
|
||||
Resource.Loading(),
|
||||
Resource.Success(listOf(FavouriteContent(content, true))),
|
||||
Resource.Loading()
|
||||
)
|
||||
|
||||
val actual = async(testDispatcher) {
|
||||
sut.get().take(3).toList()
|
||||
}
|
||||
testDispatcher.advanceUntilIdle()
|
||||
fun loadingThenDataThenLoadingReactsProperly() = runTest {
|
||||
favouriteContentIdFlow.value = listOf(ContentId("a"))
|
||||
val content = Content(ContentId("a"), "b", "c", ImageUrl("d"))
|
||||
contentFlow.value = Resource.Loading()
|
||||
val expected = listOf(
|
||||
Resource.Loading(),
|
||||
Resource.Success(listOf(FavouriteContent(content, true))),
|
||||
Resource.Loading()
|
||||
)
|
||||
|
||||
sut.get().test {
|
||||
contentFlow.value = Resource.Success(listOf(content))
|
||||
testDispatcher.advanceUntilIdle()
|
||||
|
||||
contentFlow.value = Resource.Loading()
|
||||
testDispatcher.advanceUntilIdle()
|
||||
|
||||
Assertions.assertEquals(expected, actual.await())
|
||||
expected.forEach { expectedItem ->
|
||||
Assertions.assertEquals(expectedItem, awaitItem())
|
||||
}
|
||||
Assertions.assertTrue(cancelAndConsumeRemainingEvents().isEmpty())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package org.fnives.test.showcase.core.content
|
|||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.test.runBlockingTest
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.fnives.test.showcase.core.storage.content.FavouriteContentLocalStorage
|
||||
import org.fnives.test.showcase.model.content.ContentId
|
||||
import org.junit.jupiter.api.Assertions
|
||||
|
|
@ -36,7 +37,7 @@ internal class RemoveContentFromFavouritesUseCaseTest {
|
|||
|
||||
@DisplayName("GIVEN contentId WHEN called THEN storage is called")
|
||||
@Test
|
||||
fun givenContentIdCallsStorage() = runBlockingTest {
|
||||
fun givenContentIdCallsStorage() = runTest {
|
||||
sut.invoke(ContentId("a"))
|
||||
|
||||
verify(mockFavouriteContentLocalStorage, times(1)).deleteAsFavourite(ContentId("a"))
|
||||
|
|
@ -45,7 +46,7 @@ internal class RemoveContentFromFavouritesUseCaseTest {
|
|||
|
||||
@DisplayName("GIVEN throwing local storage WHEN thrown THEN its propogated")
|
||||
@Test
|
||||
fun storageExceptionThrowingIsPropogated() = runBlockingTest {
|
||||
fun storageExceptionThrowingIsPropogated() = runTest {
|
||||
whenever(mockFavouriteContentLocalStorage.deleteAsFavourite(ContentId("a"))).doThrow(RuntimeException())
|
||||
|
||||
Assertions.assertThrows(RuntimeException::class.java) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package org.fnives.test.showcase.core.login
|
||||
|
||||
import kotlinx.coroutines.test.runBlockingTest
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.fnives.test.showcase.core.shared.UnexpectedException
|
||||
import org.fnives.test.showcase.core.storage.UserDataLocalStorage
|
||||
import org.fnives.test.showcase.model.auth.LoginCredentials
|
||||
|
|
@ -38,7 +38,7 @@ internal class LoginUseCaseTest {
|
|||
|
||||
@DisplayName("GIVEN empty username WHEN trying to login THEN invalid username is returned")
|
||||
@Test
|
||||
fun emptyUserNameReturnsLoginStatusError() = runBlockingTest {
|
||||
fun emptyUserNameReturnsLoginStatusError() = runTest {
|
||||
val expected = Answer.Success(LoginStatus.INVALID_USERNAME)
|
||||
|
||||
val actual = sut.invoke(LoginCredentials("", "a"))
|
||||
|
|
@ -50,7 +50,7 @@ internal class LoginUseCaseTest {
|
|||
|
||||
@DisplayName("GIVEN empty password WHEN trying to login THEN invalid password is returned")
|
||||
@Test
|
||||
fun emptyPasswordNameReturnsLoginStatusError() = runBlockingTest {
|
||||
fun emptyPasswordNameReturnsLoginStatusError() = runTest {
|
||||
val expected = Answer.Success(LoginStatus.INVALID_PASSWORD)
|
||||
|
||||
val actual = sut.invoke(LoginCredentials("a", ""))
|
||||
|
|
@ -62,7 +62,7 @@ internal class LoginUseCaseTest {
|
|||
|
||||
@DisplayName("GIVEN invalid credentials response WHEN trying to login THEN invalid credentials is returned ")
|
||||
@Test
|
||||
fun invalidLoginResponseReturnInvalidCredentials() = runBlockingTest {
|
||||
fun invalidLoginResponseReturnInvalidCredentials() = runTest {
|
||||
val expected = Answer.Success(LoginStatus.INVALID_CREDENTIALS)
|
||||
whenever(mockLoginRemoteSource.login(LoginCredentials("a", "b")))
|
||||
.doReturn(LoginStatusResponses.InvalidCredentials)
|
||||
|
|
@ -75,7 +75,7 @@ internal class LoginUseCaseTest {
|
|||
|
||||
@DisplayName("GIVEN success response WHEN trying to login THEN session is saved and success is returned")
|
||||
@Test
|
||||
fun validResponseResultsInSavingSessionAndSuccessReturned() = runBlockingTest {
|
||||
fun validResponseResultsInSavingSessionAndSuccessReturned() = runTest {
|
||||
val expected = Answer.Success(LoginStatus.SUCCESS)
|
||||
whenever(mockLoginRemoteSource.login(LoginCredentials("a", "b")))
|
||||
.doReturn(LoginStatusResponses.Success(Session("c", "d")))
|
||||
|
|
@ -89,7 +89,7 @@ internal class LoginUseCaseTest {
|
|||
|
||||
@DisplayName("GIVEN error resposne WHEN trying to login THEN session is not touched and error is returned")
|
||||
@Test
|
||||
fun invalidResponseResultsInErrorReturned() = runBlockingTest {
|
||||
fun invalidResponseResultsInErrorReturned() = runTest {
|
||||
val exception = RuntimeException()
|
||||
val expected = Answer.Error<LoginStatus>(UnexpectedException(exception))
|
||||
whenever(mockLoginRemoteSource.login(LoginCredentials("a", "b")))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package org.fnives.test.showcase.core.login.hilt
|
||||
|
||||
import kotlinx.coroutines.test.runBlockingTest
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.fnives.test.showcase.core.content.ContentRepository
|
||||
import org.fnives.test.showcase.core.login.LogoutUseCase
|
||||
import org.fnives.test.showcase.core.storage.UserDataLocalStorage
|
||||
|
|
@ -22,6 +22,7 @@ internal class LogoutUseCaseTest {
|
|||
lateinit var sut: LogoutUseCase
|
||||
private lateinit var mockUserDataLocalStorage: UserDataLocalStorage
|
||||
private lateinit var testCoreComponent: TestCoreComponent
|
||||
|
||||
@Inject
|
||||
lateinit var contentRepository: ContentRepository
|
||||
|
||||
|
|
@ -45,7 +46,7 @@ internal class LogoutUseCaseTest {
|
|||
|
||||
@DisplayName("WHEN logout invoked THEN storage is cleared")
|
||||
@Test
|
||||
fun logoutResultsInStorageCleaning() = runBlockingTest {
|
||||
fun logoutResultsInStorageCleaning() = runTest {
|
||||
val repositoryBefore = contentRepository
|
||||
|
||||
sut.invoke()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package org.fnives.test.showcase.core.login.koin
|
||||
|
||||
import kotlinx.coroutines.test.runBlockingTest
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.fnives.test.showcase.core.content.ContentRepository
|
||||
import org.fnives.test.showcase.core.di.koin.createCoreModule
|
||||
import org.fnives.test.showcase.core.login.LogoutUseCase
|
||||
|
|
@ -56,7 +57,7 @@ internal class LogoutUseCaseTest : KoinTest {
|
|||
|
||||
@DisplayName("WHEN logout invoked THEN storage is cleared")
|
||||
@Test
|
||||
fun logoutResultsInStorageCleaning() = runBlockingTest {
|
||||
fun logoutResultsInStorageCleaning() = runTest {
|
||||
val repositoryBefore = getKoin().get<ContentRepository>()
|
||||
|
||||
sut.invoke()
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package org.fnives.test.showcase.core.shared
|
|||
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.fnives.test.showcase.model.shared.Answer
|
||||
import org.fnives.test.showcase.model.shared.Resource
|
||||
import org.fnives.test.showcase.network.shared.exceptions.NetworkException
|
||||
|
|
@ -15,7 +16,7 @@ internal class AnswerUtilsKtTest {
|
|||
|
||||
@DisplayName("GIVEN network exception thrown WHEN wrapped into answer THEN answer error is returned")
|
||||
@Test
|
||||
fun networkExceptionThrownResultsInError() = runBlocking {
|
||||
fun networkExceptionThrownResultsInError() = runTest {
|
||||
val exception = NetworkException(Throwable())
|
||||
val expected = Answer.Error<Unit>(exception)
|
||||
|
||||
|
|
@ -26,7 +27,7 @@ internal class AnswerUtilsKtTest {
|
|||
|
||||
@DisplayName("GIVEN parsing exception thrown WHEN wrapped into answer THEN answer error is returned")
|
||||
@Test
|
||||
fun parsingExceptionThrownResultsInError() = runBlocking {
|
||||
fun parsingExceptionThrownResultsInError() = runTest {
|
||||
val exception = ParsingException(Throwable())
|
||||
val expected = Answer.Error<Unit>(exception)
|
||||
|
||||
|
|
@ -37,7 +38,7 @@ internal class AnswerUtilsKtTest {
|
|||
|
||||
@DisplayName("GIVEN unexpected throwable thrown WHEN wrapped into answer THEN answer error is returned")
|
||||
@Test
|
||||
fun unexpectedExceptionThrownResultsInError() = runBlocking {
|
||||
fun unexpectedExceptionThrownResultsInError() = runTest {
|
||||
val exception = Throwable()
|
||||
val expected = Answer.Error<Unit>(UnexpectedException(exception))
|
||||
|
||||
|
|
@ -48,7 +49,7 @@ internal class AnswerUtilsKtTest {
|
|||
|
||||
@DisplayName("GIVEN string WHEN wrapped into answer THEN string answer is returned")
|
||||
@Test
|
||||
fun stringIsReturnedWrappedIntoSuccess() = runBlocking {
|
||||
fun stringIsReturnedWrappedIntoSuccess() = runTest {
|
||||
val expected = Answer.Success("banan")
|
||||
|
||||
val actual = wrapIntoAnswer { "banan" }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue