I am trying to add tests to test Controller, but mock the dependencies.
@MicronautTest
class PostControllerTest(private val posts: PostRepository, @Client("/") private val client: HttpClient) : StringSpec({
"test get posts endpoint" {
every { posts.findAll() }
.returns(
listOf(
Post(
id = UUID.randomUUID(),
title = "test title",
content = "test content",
status = Status.DRAFT,
createdAt = LocalDateTime.now()
)
)
)
val request = HttpRequest.GET<Any>("/posts")
val bodyType = Argument.listOf(Post::class.java).type
val response = client.toBlocking().exchange(request, bodyType)
response.status shouldBe HttpStatus.OK
response.body()!![0].title shouldBe "test title"
verify(exactly = 1) { posts.findAll() }
}
@MockBean(PostRepository::class)
fun posts() = mockk<PostRepository>()
})
This does not work, due to the mocked PostRepsoitory
can not be recognized.
Changed to the following when running tests.
@MicronautTest
class PostControllerTest(
private val postsBean: PostRepository,
@Client("/") private var client: HttpClient
) : FunSpec({
test("test get posts endpoint") {
val posts = getMock(postsBean)
every { posts.findAll() }
.returns(
listOf(
Post(
id = UUID.randomUUID(),
title = "test title",
content = "test content",
status = Status.DRAFT,
createdAt = LocalDateTime.now()
)
)
)
val request = HttpRequest.GET<Any>("/posts")
val bodyType = Argument.listOf(Post::class.java).type
val response = client.toBlocking().exchange(request, bodyType)
response.status shouldBe HttpStatus.OK
response.body()!![0].title shouldBe "test title"
verify(exactly = 1) { posts.findAll() }
}
}) {
@MockBean(PostRepository::class)
fun posts() = mockk<PostRepository>()
}
And got the exception like this.
io.micronaut.context.exceptions.BeanInstantiationException: Error instantiating bean of type [com.example.PostControllerTest]
Message: Retrieving the port from the server before it has started is not supported when binding to a random port
Path Taken: new DataInitializer(PostRepository posts) --> new DataInitializer([PostRepository posts]) --> new PostControllerTest(PostRepository postsBean,[HttpClient client])
The DataInitializer
is used to listen StartupEvent
and insert sample data. How to make sure the application is started successfully before running the tests.
The complete code is here.
There is another mock example written in Junit5 and Mockito, it works well.