I'm writing a test that takes longer than 15 secon...
# javascript
m
I'm writing a test that takes longer than 15 seconds to execute and I'm getting this error:
Error: Timeout of 15000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.
Here is my
runTest { ... }
function:
Copy code
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.promise

val testScope = MainScope()
val testCoroutineContext = testScope.coroutineContext

actual fun runTest(
    block: suspend (scope: CoroutineScope) -> Unit
): dynamic = testScope.promise(
    start = CoroutineStart.UNDISPATCHED,
    context = testCoroutineContext,
) {
    block(this)
}
And a simple test to verify:
Copy code
class SimpleTest {
    @Test fun testShortDelay() = runTest { delay(10_000) } // passes
    @Test fun testLongDelay() = runTest { delay(15_001) } // fails (I want it to pass)
}
Does anybody know what I should change in
runTest
to get
testLongDelay
and
testShortDelay
to both pass? I've tried a number of things and nothing seems to work.
n
Does
testShortDelay
actually take 10 seconds to execute? If so, that's your problem, because `delay`s are supposed to be skipped within
runTest
.
m
@nschulzke
n
Are you implementing your own
runTest
because JS doesn't have one built in?
m
Yeah, correct
n
Actually, that says it's in
common
, the jvm version is deprecated and just calls the common version.
m
👀
n
There's also this note in the doc comments for runTest:
Copy code
* On JS, this function creates a `Promise` that executes the test body with the delay-skipping behavior.
m
There an easy way to see what version introduced it?
That does seem to be what I am looking for
n
Doesn't look like it. I'm on kxcoroutines version 1.6.4.
m
Yeah that's latest
I'm 1.6.2 oddly enough
Pardon the pun but that's... promising
n
I doubt much has changed since then in runTest.
XD
m
Trying to see how I can use that now...
This is going to take a bit of finagling to use all the places I want to, but I think this is a path forward. Thank you @nschulzke
@nschulzke in this case I do actually need the delay functionality, so I've done this to my runTest function:
Copy code
/**
 * See [kotlinxRunTest] for more details.
 */
@OptIn(ExperimentalCoroutinesApi::class)
fun runTest(
    dispatchTimeoutMs: Long = DEFAULT_TIMEOUT_MS,
    block: suspend (scope: CoroutineScope) -> Unit
): TestResult {
    return kotlinxRunTest(dispatchTimeoutMs = dispatchTimeoutMs) {
        withContext(Dispatchers.Default) {
            block(this@withContext)
        }
    }
}
testLongDelay
still fails for the same reason 😞
And DEFAULT_TIMEOUT_MS is 30_000L here
And the message still says 15000ms
We can go even simpler:
Copy code
@Test
    fun testLongDelay() = kotlinx.coroutines.test.runTest (dispatchTimeoutMs = 16000) {
        withContext(Dispatchers.Default) {
            withTimeout(16000) {
                delay(15001)
            }
        }
    }
The above throws error:
Copy code
Error: Timeout of 15000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.
Error: Timeout of 15000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.
	at <global>.listOnTimeout(node:internal/timers:557)
	at <global>.processTimers(node:internal/timers:500)
a
Kotlin uses mocha under the hood for testing, so you need to tell mocha as well that your tests are going to take a little bit longer
You can do that by creating a
karma.config.d
folder that is in the same leve as your
build.gradle(.kts)
and inside create a js file (I call mine
timeout.js
) and set your timeout like so
Copy code
config.set({
  "client": {
    "mocha": {
      "timeout": 15000
    },
  },
  "browserDisconnectTimeout": 15000
});
🎯 1