Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

In testing - Scope cannot be cancelled because it does not have a job #2379

Closed
joancolmenerodev opened this issue Nov 10, 2020 · 1 comment
Closed
Assignees
Labels

Comments

@joancolmenerodev
Copy link

@joancolmenerodev joancolmenerodev commented Nov 10, 2020

We are trying to check that the scope is canceled on a Test.
We have injected via constructor the scope and dispatcher, for instance MainScope() and Dispatchers.IO, this works good, now we want to ensure that when we call one method the scope is canceled.

Example code

class ExampleClass @Inject constructor(val scope: CoroutineScope, val dispatcher: CoroutineDispatcher, val service: MyService){
    fun example(){
         scope.launch{withContext(dispatcher){service.getExamples()}.fold{..},{..})
    }

    fun methodToTest(){
        scope.cancel()
    }
}

Note: this service is a fake API call, which requires network operations, we can test the example, but when trying to test the methodToTest which contains the scope.cancel() is not working for us.

Problem?

On test, we are using

val dispatcher = TestCoroutineDispatcher()
val scope = TestCoroutineScope(dispatcher)

It works, but when trying to use this

scope.coroutineContext.isCanceled

It throws

Scope cannot be canceled because it does not have a Job

Investigating a little bit, we noticed that TestCoroutineScope is creating a default context EmptyCoroutineContext and the problem is that This CoroutineContext doesn't have a Job() so it's not possible to check if it's canceled or not.

What we can do and actually fixes the problem is to initialize the scope as

val scope = TestCoroutineScope(Job() + dispatcher)

It solves the problem, but we think that it's not the proper way because is using the "real" implementation of a Job() and there are a lot of unnecessary things that we don't need.

Is there any way to test it without passing a real Job()?

@elizarov elizarov added the test label Nov 10, 2020
@neworld
Copy link

@neworld neworld commented Nov 19, 2020

Also, #2312 is not working there, because TestCoroutineScope() does not have a job. But it is expected in the description of the issue #2159

This !! cast always succeeds, but it draws the developer's attention and brings in uncertainty about the correctness of the code.

Also, I found CoroutineScope(EmptyCoroutineContext) has a job.

@dkhalanskyjb dkhalanskyjb self-assigned this Oct 11, 2021
yorickhenning pushed a commit to yorickhenning/kotlinx.coroutines that referenced this issue Jan 28, 2022
This commit introduces the new version of the test module.
Please see README.md and MIGRATION.md for a thorough
discussion of the changes.

Fixes Kotlin#1203
Fixes Kotlin#1609
Fixes Kotlin#2379
Fixes Kotlin#1749
Fixes Kotlin#1204
Fixes Kotlin#1390
Fixes Kotlin#1222
Fixes Kotlin#1395
Fixes Kotlin#1881
Fixes Kotlin#1910
Fixes Kotlin#1772
Fixes Kotlin#1626
Fixes Kotlin#1742
Fixes Kotlin#2082
Fixes Kotlin#2102
Fixes Kotlin#2405
Fixes Kotlin#2462

Co-authored-by: Vsevolod Tolstopyatov <qwwdfsad@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

4 participants