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

asserts should support kotlin coroutines support. #675

Closed
hs-kdhillon opened this issue Apr 2, 2020 · 6 comments
Closed

asserts should support kotlin coroutines support. #675

hs-kdhillon opened this issue Apr 2, 2020 · 6 comments

Comments

@hs-kdhillon
Copy link

I am trying to test network connectivity and by method is a suspend function. It work be nice if there is coroutine support present like mockito provides, for example, coAssertThat().

Currently, we need to wrap the assert call inside runBlocking{} scope.
runBlocking { assertThat(mockNetworkInfo.isConnected()) }

it would be nice if this support is provided so that all we need to do is:
coAssertThat(mockNetworkInfo.isConnected())

@JakeWharton
Copy link

That is impossible as the isConnected() call executes in the context of the enclosing function body not inside assertThat. assertThat is just receiving a boolean. This is an entirely orthogonal problem to the assertion library. What you want is like @Test suspend fun foo() {} which is tracked at https://youtrack.jetbrains.com/issue/KT-22228.

@hs-kdhillon
Copy link
Author

hs-kdhillon commented Apr 3, 2020

runBlocking {
    val result = repository.getConcreteNumberTrivia(number)
    coVerify { mockRemoteDataSource.getConcreteNumberTrivia(number) }
    assertThat(result).isEqualTo(Success(entity))
}

Here the only suspending function is

val result = repository.getConcreteNumberTrivia(number)

And the only thing i am interested in doing is

assertThat(repository.getConcreteNumberTrivia(number)).isEqualTo(Success(entity))

I feel like there should be a shortcut for where we don't need to create these runBlocking scopes or to create result variables to hold the result.

@JakeWharton
Copy link

And the only thing i am interested in doing is

assertThat(repository.getConcreteNumberTrivia(number)).isEqualTo(Success(entity))

From Truth's perspective, this is functionality equivalent to

assertThat(Success(entity)).isEqualTo(Sucess(entity))

The library is not invoking your suspend function and thus has no control over it. Your test body invokes the suspend function and, thus, your test body needs runBlocking.

What you're asking for is a framework that supports writing

@Test suspend fun myTest() {
    val result = repository.getConcreteNumberTrivia(number)
    coVerify { mockRemoteDataSource.getConcreteNumberTrivia(number) }
    assertThat(result).isEqualTo(Success(entity))
}

which has nothing to do with Truth and is what I linked earlier.

@hs-kdhillon
Copy link
Author

hs-kdhillon commented Apr 3, 2020

True, makes sense. Is there any such XUnit framework that supports this? I see that a issue is opened for JUnit 5 to support this junit-team/junit5#1914

PS: Big fan jake ✌️

@JakeWharton
Copy link

I do not know of any. But I'll start following that JUnit 5 issue (despite being extremely bearish on 5.x).

If you wanted to get really, really creative with JUnit 4 I believe you can do this as a custom test runner. You would discover the test methods yourself which would be in the form

@Test public Object testName(Continuation<? extends Unit> continuation)

and then invoke them with some very low-level coroutine machinery.

I could be convinced to be nerd-sniped by this task... I just have to find the time...

And, of course, the big problem here is that JUnit 4 test runners do not compose so you couldn't combine it with parameterized or anything else.

@hs-kdhillon
Copy link
Author

Sounds good will try to implement this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants