Mockito:需要但未调用 Webflux Spring 启动
Mockito: Wanted but not invoked Webflux Spring boot
这似乎是 Whosebug 上的一个有据可查的问题,但似乎没有一个解决方案对我有用(如果我错了,如果有人指出我的解决方案,我会很高兴)。我正在关注 this tutorial 如何在 Spring 启动时测试 Webflux 控制器。我做了我认为正是教程中的内容,但出于某种原因,我收到以下错误:
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.
这是我的控制器
@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 = "testuser@gmail.com", 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
}
}
我哪里会出错?
如果我理解正确,WordServiceImpl
是 WordRepository
的包装器。对存储库的每次调用都通过服务。由于您已模拟该服务,因此这些操作不会进入存储库。
如果您想断言存储库交互,请不要模拟 WordServiceImpl
或改用间谍。
当您创建 class 的模拟对象时,您必须定义它的行为,因为模拟对象不充当 class 的原始实例。
你可以使用 spy 而不是 mock,如果你不通过模拟它的方法来告诉其他人,它的行为就像原始实例一样。
您可以执行以下任一操作:
- 删除
@MockBean lateinit var wordService: WordServiceImpl
或
WordServiceImpl
使用 @SpyBean
而不是 @MockBean
但如果我是你,我会选择第一个选项,因为对你没有使用的对象使用 @SpyBean
真的没有意义
这似乎是 Whosebug 上的一个有据可查的问题,但似乎没有一个解决方案对我有用(如果我错了,如果有人指出我的解决方案,我会很高兴)。我正在关注 this tutorial 如何在 Spring 启动时测试 Webflux 控制器。我做了我认为正是教程中的内容,但出于某种原因,我收到以下错误:
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.
这是我的控制器
@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 = "testuser@gmail.com", 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
}
}
我哪里会出错?
如果我理解正确,WordServiceImpl
是 WordRepository
的包装器。对存储库的每次调用都通过服务。由于您已模拟该服务,因此这些操作不会进入存储库。
如果您想断言存储库交互,请不要模拟 WordServiceImpl
或改用间谍。
当您创建 class 的模拟对象时,您必须定义它的行为,因为模拟对象不充当 class 的原始实例。
你可以使用 spy 而不是 mock,如果你不通过模拟它的方法来告诉其他人,它的行为就像原始实例一样。
您可以执行以下任一操作:
- 删除
@MockBean lateinit var wordService: WordServiceImpl
或 WordServiceImpl
使用
@SpyBean
而不是 @MockBean
但如果我是你,我会选择第一个选项,因为对你没有使用的对象使用 @SpyBean
真的没有意义