Last active
February 19, 2020 11:28
-
-
Save GuilhE/18afc4d510e245fba39c8917279d36ad to your computer and use it in GitHub Desktop.
OperatorExtensions tests with MockK
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import io.mockk.clearAllMocks | |
import kotlinx.coroutines.Dispatchers | |
import kotlinx.coroutines.ExperimentalCoroutinesApi | |
import kotlinx.coroutines.delay | |
import kotlinx.coroutines.test.TestCoroutineDispatcher | |
import kotlinx.coroutines.test.resetMain | |
import kotlinx.coroutines.test.runBlockingTest | |
import kotlinx.coroutines.test.setMain | |
import org.assertj.core.api.Assertions.assertThat | |
import org.junit.jupiter.api.* | |
import org.junit.jupiter.api.extension.ExtendWith | |
@ExtendWith(InstantExecutorExtension::class) | |
@TestInstance(TestInstance.Lifecycle.PER_CLASS) | |
class OperatorExtensionsTest { | |
//Documentation is your friend: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-test/ | |
@ExperimentalCoroutinesApi | |
private val testDispatcher = TestCoroutineDispatcher() | |
@BeforeAll | |
@ExperimentalCoroutinesApi | |
fun setupDispatchers() { | |
Dispatchers.setMain(testDispatcher) | |
} | |
@AfterAll | |
@ExperimentalCoroutinesApi | |
fun clearDispatchers() { | |
Dispatchers.resetMain() | |
testDispatcher.cleanupTestCoroutines() | |
} | |
@AfterEach | |
fun clear() { | |
clearAllMocks() | |
} | |
@Test | |
@ExperimentalCoroutinesApi | |
fun `When throttleFirst is called, Then it will emmit the first item and skip all the following emissions until a certain time interval is respected`() { | |
var timesReturned = 0 | |
lateinit var throttleFirstFx: (Unit) -> Unit | |
testDispatcher.runBlockingTest { | |
throttleFirstFx = throttleFirst(1_000, this, action = { timesReturned++ }) | |
repeat(3) { throttleFirstFx(Unit) } //only one emission will hapen | |
assertThat(timesReturned).isEqualTo(1) | |
repeat(3) { | |
delay(1_000) | |
throttleFirstFx(Unit) //3 emissions | |
} | |
} | |
assertThat(timesReturned).isEqualTo(4) //(1+3) | |
} | |
@Test | |
@ExperimentalCoroutinesApi | |
fun `When throttleLatest is called, Then it returns the latest data after a time interval without emissions`() { | |
var valueReturned = 0 | |
lateinit var throttleLatestFx: (Int) -> Unit | |
testDispatcher.runBlockingTest { | |
throttleLatestFx = throttleLatest(500, this, action = { value -> valueReturned = value }) | |
throttleLatestFx(1) | |
throttleLatestFx(2) | |
throttleLatestFx(3) | |
assertThat(valueReturned).isEqualTo(0) //nothing changed so far, we didn't respect the 500ms interval of emission, yet... | |
delay(500) //Note that without runBlockingTest 520ms is the minimum precision | |
assertThat(valueReturned).isEqualTo(3) //now that we have and the last emitted was throttleLatestFx(3), valueReturned will be 3 | |
throttleLatestFx(4) | |
} | |
assertThat(valueReturned).isEqualTo(4) //the runBlocking will wait until completion so valueReturned will be 4. | |
} | |
@Test | |
@ExperimentalCoroutinesApi | |
fun `When debounce is called it, Then returns only if there's no new data emission for a desired time interval`() { | |
var timesReturned = 0 | |
val action: (Unit) -> Unit = { timesReturned++ } | |
lateinit var debounceFx: (Unit) -> Unit | |
testDispatcher.runBlockingTest { | |
debounceFx = debounce(500, this, action = action) | |
repeat(2) { | |
debounceFx(Unit) | |
} | |
delay(600) //now that we've waited at least >500ms, let's emit the latest call, thus timesReturned = 1 | |
assertThat(timesReturned).isEqualTo(1) | |
repeat(2) { | |
debounceFx(Unit) | |
delay(600) //each cycle we wait 600ms, all emissions will be fired, thus timesReturned = (1+2) | |
} | |
} | |
assertThat(timesReturned).isEqualTo(3) | |
} | |
@Test | |
@ExperimentalCoroutinesApi | |
fun `When throttleClick is used, Then all supersonic clicks will be avoided, useful for UI`() { | |
var timesReturned = 0 | |
testDispatcher.runBlockingTest { | |
val clickFx = throttleClick( this, clickAction = { timesReturned++ }) | |
repeat(100) { clickFx(Unit) } | |
} | |
assertThat(timesReturned).isEqualTo(1) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment