I figured out a way to mock a postRepository (in a...
# spring
d
I figured out a way to mock a postRepository (in a spring reactive project with Kotlin). I have this class:
Copy code
@ContextConfiguration
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class PostControllerTest(@Autowired val webTestClient: WebTestClient) {

    @MockkBean
    lateinit var postService: PostService

    lateinit var postRepository: PostRepository

    @BeforeEach
    fun setUp() {
        postRepository = mockk()
    }

    @Test
    fun `GIVEN valid data WHEN a post is submitted THEN the post is returned`() {
        // Given
        val postDto = PostFactory(postRepository).makeOne(1)

        coEvery { postService.create(1, postDto) } returns postDto
Can someone can confirm this is the right way to do it ? My concern is regarding the PostRepository. I think because of lateinit, PostRepository is not created and because I initialize it with mockk(), then it will only be mocked. Right ? : https://github.com/danygiguere/spring-boot-3-reactive-with-kotlin-coroutines/blob/main/src/test/kotlin/com/example/demo/unit/PostControllerTest.kt
r
the BeforeEach block will re-initialize the variable before every test case, so it shouldn't be null in your usecases. You could have used a
@MockkBean
as you also did to your service, and use the
clearAllMocks()
function Mockk provides to only block mocks from leaking from test case to test case. However, it seems like your Repository will not be called, given that you are mocking the Service class that ultimately calls it. If you are mocking specific services, it can be good to also
verify / coVerify
that the calls happened as expected, depending on the business context Ultimately, for database integration tests, I would recommend looking into TestContainers or similar to spin up a test database so your integration tests can be more accurate to a real life scenario
d
Thanks a lot for the valuable info @renatomrcosta. I wasn’t able to make it work with @MockkBean. 1: would you add the clearAllMocks() in a @BeforeEach function ? 2: For the TestContainers. Is it the same if I add a application-test.yml and set the connection to another db (reserved for tests) ?
r
1. Yes, generally speaking. Either rebuilding the mocks per test unit, or clearing their mocks after every test. 2. Yes, but this sounds like a nightmare. Ideally, you want your tests to be in a controlled environment: when you start every spec, the database has to have the same records and same behavior and should be reset to its initial state per test or spec. Having a shared state in which multiple developers can create or remove values while working will likely lead to headaches down the line (inconsistent state, flaky tests, etc)
👍 1
105 Views