Does any have experience using `Mockk` I am trying...
# test
l
Does any have experience using
Mockk
I am trying to mock the following function
Copy code
fun <T> openAndCloseSession(handler: (Session) -> T): T {
    val session = HibernateUtil.sessionFactory.openSession()
    val res = handler(session)
    if (session.isOpen) {
        session.close()
    } else {
        println("[WARNING]: session closed by handler function: ${handler::class.java.enclosingMethod}, please consider omitting manually closing the session in the handler as it will be closed automatically at the end of the call")
    }
    return res
}
I want the mock to just call the provided
handler
(which I have mocked too). This is where I am currently at
Copy code
val session: Session = mockk()
every { openAndCloseSession<Any>(any()) } answers {firstArg<(Session) -> Any>().invoke(session)}
Sadly this doesn't work.
t
Can you clarify - are you mocking
handler
or this entire function?
l
My problem was the fact that I was mocking a top level/static function and I hadn't called
mockkStatic(..)
.
And to answer your question, I was mocking both but my question was about mocking the function itself (I had already mocked the handler).
t
This is where my confusion stems from - if you’re mocking the function, where does the handler come into the picture?
l
I have a REST endpoint which calls
openAndCloseSession
to create a new Hibernate session which will remain open within the handler in which an action is performed (usually a DAO function) and returns the results of the handler. I just want to test my endpoint, I mocked the (DAO) functions that my endpoints call, I wanted to skip the creation of the Hibernate session and the mocked function to just call the handler immediately as the handler is mocked anyway. I hope it makes sense 😅
t
For purely testing your endpoint, it might be better to have that call something that isn’t related to hibernate/daos’/etc. Just have it work on an interface that performs the action and mock that instead. Alot of this pain will then go away
l
You mean I should alter my actual endpoint or my test? I don't think I quite understand.
t
I assume your endpoint has your DAO injected into it?
It might help if you just show your endpoint code
l
Copy code
@Path(PersonPaths.ROOT)
@Produces(MediaType.APPLICATION_JSON)
actual class PersonEndpoint : Endpoint() {

    @GET
    @Path(PersonPaths.GET_BY_ID)
    actual suspend fun getById(@PathParam("id") id: Long): PersonDTO = openAndCloseSession {
        val genericDaoImpl = GenericDaoImpl<Person, Long>(Person::class.java, it)
        genericDaoImpl.load(id)
    }?.dto ?: throw WebApplicationException(Response.Status.NOT_FOUND)

    @GET
    actual suspend fun getAll(): List<PersonDTO> = openAndCloseSession {
        val genericDaoImpl = GenericDaoImpl<Person, Long>(Person::class.java, it)
        genericDaoImpl.loadAll()
    }.map { it.dto }

    @GET
    @Path(PersonPaths.RESULTS_LIST_PATH)
    actual suspend fun getAllResultsList(): ResultsList<PersonDTO> = ResultsList(openAndCloseSession {
        val genericDaoImpl = GenericDaoImpl<Person, Long>(Person::class.java, it)
        genericDaoImpl.loadAll()
    }.map { it.dto })


    @POST
    @Status(201)
    actual suspend fun create(personDTO: PersonDTO): Long = openAndCloseSession {
        val genericDaoImpl = GenericDaoImpl<Person, Long>(Person::class.java, it)
        genericDaoImpl.save(personDTO.entity)
    }

}