Hello, I have a mocked object and trying to setup `coEvery` to mock a specific function although som...
a
Hello, I have a mocked object and trying to setup
coEvery
to mock a specific function although somehow the
coEvery
call is hanging when I run the test. What can cause this hanging?
m
is the function you are mocking suspend?
👍 1
a
Think I’ve found the problem, it was due to mocking it twice
m
do you have a full reproducible example? I’d like to take a look
👀 1
a
I’m mocking a
CoroutineCollection
from KMongo and using this function that I’ve came up with to do it regarding this
Copy code
inline fun <reified T : Any> mockkCoroutineCollection(
    name: String? = null,
    relaxed: Boolean = false,
    vararg moreInterfaces: KClass<*>,
    relaxUnitFun: Boolean = false,
    block: MongoCollection<T>.() -> Unit = {}
): MongoCollection<T> = mockk(name, relaxed, *moreInterfaces, relaxUnitFun = relaxUnitFun) {
    mockkStatic(MongoCollection<T>::coroutine)
    val that = this
    every { coroutine } returns mockk(name, relaxed, *moreInterfaces, relaxUnitFun = relaxUnitFun) {
        every { collection } returns that
    }
    block()
}
And I have a service which receives the database and obtains both collections and seems that from the order I call it the mock doesn’t capture type information
Now trying to figure it out if I can return the respective collection for the specified type
Some more context here
Copy code
data class User(val id: Int, val name: String)
data class Book(val id: Int, val name: String)

class Service(private val myDatabase: CoroutineDatabase) {
    private val userCollection: CoroutineCollection<User> = myDatabase.getCollection("users")
    private val booksCollection: CoroutineCollection<Book> = myDatabase.getCollection("books")

    fun getUserById(id: Int): User? = userCollection.findOneById(id)
    fun getBookById(id: Int): Book? = booksCollection.findOneById(id)
    // ...
}

fun test() {
    val mongoDatabase = mockkCoroutineDatabase(relaxed = true)
    val usersCollection = mockkCoroutineCollection<User>(relaxed = true)
    val booksCollection = mockkCoroutineCollection<Book>(relaxed = true)
    val coroutineUsers: CoroutineCollection<User> = usersCollection.coroutine
    val coroutineBooks: CoroutineCollection<Book> = booksCollection.coroutine

    every {
        mongoDatabase.getCollection(any(), User::class.java)
    } returns usersCollection

    every {
        mongoDatabase.getCollection(any(), Book::class.java)
    } returns booksCollection

    val sut: Service = Service(mongoDatabase)
    

    val expectedUser = User(20, "Joe")

    // depending on the order I create the mocked collections this hangs or not
    coEvery {
        coroutineUsers.findOneById(any())
    } returns expectedUser

    assertEquals(expectedUser, sut.getUserById(20))
}
Basically if I switch the two lines that call
mockkCoroutineCollection
this will pass
@Mattia Tommasone any ideias? 😅
m
not many ideas on how to solve it, but i’m guessing the issue is with the fact that
MongoCollection<T>::coroutine
is static, so
mockkStatic
-ing it more than once leads to recorded calls being erased
a
the thing is the
every { coroutine } returns 

doesn’t capture type information
Think I figured it out
just did
every { ofType<MongoCollection<T>>().coroutine } returns 

m
ah nice, that makes sense
a
binding the type to the mock
guess it was doing any().coroutine
438 Views