Home > Blockchain >  Mockito: Wanted but not invoked Webflux Spring boot
Mockito: Wanted but not invoked Webflux Spring boot

Time:04-11

It seems this is a well-documented issue here on Stackoverflow but it seems non of the solutions are working for me (if I am wrong I'd be glad if someone pointed me to a solution). I was following this tutorial on how to test Webflux controllers in Spring boot. I did what I believe is exactly what is in the tutorial but for some reason, I am getting the error below:

    Wanted but not invoked:
wordRepository bean.save(
    Word(word=test word, id=0, updatedAt=2022-04-11T01:19:10.275631, createdAt=2022-04-11T01:19:10.275631)
);
-> at com.freeman.hangman.controller.WordControllerImplTest.givenWordDTO_expectedCreateWord(WordControllerImplTest.kt:78)
Actually, there were zero interactions with this mock.

Wanted but not invoked:
wordRepository bean.save(
    Word(word=test word, id=0, updatedAt=2022-04-11T01:19:10.275631, createdAt=2022-04-11T01:19:10.275631)
);
-> at com.freeman.hangman.controller.WordControllerImplTest.givenWordDTO_expectedCreateWord(WordControllerImplTest.kt:78)
Actually, there were zero interactions with this mock.

This is my controller

@ExtendWith(SpringExtension::class)
@WebFluxTest(WordControllerImpl::class)
@Import(WordServiceImpl::class)
class WordControllerImplTest {

    @Autowired
    lateinit var webClient: WebTestClient

    @MockBean
    lateinit var wordService: WordServiceImpl

    @MockBean
    lateinit var wordRepository: WordRepository


    private val CURRENT_DATE_TIME = LocalDateTime.now()
    private val TEST_WORD_ID = 1


    @Test
    @WithMockUser(username = "[email protected]", authorities = ["ROLE_USER", "ROLE_ADMIN"], password = "pwd")
    fun givenWordDTO_expectedCreateWord(){
        val wordDto = WordDto(word = "test word", id = 0, createdAt = CURRENT_DATE_TIME.toString())
        val word = Word("test word", 0, CURRENT_DATE_TIME, CURRENT_DATE_TIME)
        `when`(wordRepository.save(word)).thenReturn(Mono.just(word))

        webClient.mutateWith(csrf()).post()
            .uri("/freeman-hangman/words/create")
            .contentType(MediaType.APPLICATION_JSON)
            .body(BodyInserters.fromValue(wordDto))
            .exchange()
            .expectStatus()
            .isCreated

        verify(wordRepository, times(1)).save(word)//this is where the error is happening
    }

}

Where can I be going wrong?

CodePudding user response:

If I understood correctly, WordServiceImpl is kind of wrapper to WordRepository. Every call to repository goes through service. Since you have mocked the service, those actions don't go to the repository.

If you want to assert repository interaction, don't mock WordServiceImpl or use spy instead.

When you create a mock object of a class, you have to define its behavior, since the mocked object does not act as the original instance of the class.

You can use spy instead of mock which behaves like the original instance if you don't tell the otherwise via mocking its methods.

You can do either:

  1. Delete @MockBean lateinit var wordService: WordServiceImpl or
  2. Use @SpyBean instead of @MockBean for WordServiceImpl

But if I were you, I would choose the first option, since it doesn't really make sense to use @SpyBean for an object that you didn't use

  • Related