mockito check/match 参数值是否在验证中
Does mockito check/match argument values in verify
在这个测试用例中,我想检查一个函数是否调用了特定的编号。具有特定值的次数
"add tag information in supported tags" in {
val servicesTestEnv = new ServicesTestEnv(components = components)
val questionTransactionDBService = new QuestionsTransactionDatabaseService(
servicesTestEnv.mockAnswersTransactionRepository,
servicesTestEnv.mockPartitionsOfATagTransactionRepository,
servicesTestEnv.mockPracticeQuestionsTagsTransactionRepository,
servicesTestEnv.mockPracticeQuestionsTransactionRepository,
servicesTestEnv.mockSupportedTagsTransactionRepository,
servicesTestEnv.mockUserProfileAndPortfolioTransactionRepository,
servicesTestEnv.mockQuestionsCreatedByUserRepo,
servicesTestEnv.mockTransactionService,
servicesTestEnv.mockPartitionsOfATagRepository,
servicesTestEnv.mockHelperMethods
)
when(servicesTestEnv.mockTransactionService.start)
.thenReturn(servicesTestEnv.mockDistributedTransaction)
doNothing().when(servicesTestEnv.mockPracticeQuestionsTransactionRepository).add(ArgumentMatchers.any[DistributedTransaction],ArgumentMatchers.any[PracticeQuestion],ArgumentMatchers.any[MutationCondition])
doNothing().when(servicesTestEnv.mockPracticeQuestionsTagsTransactionRepository).add(ArgumentMatchers.any[DistributedTransaction],ArgumentMatchers.any[PracticeQuestionTag],ArgumentMatchers.any[MutationCondition])
when(servicesTestEnv.mockPartitionsOfATagTransactionRepository.get(ArgumentMatchers.any[DistributedTransaction],ArgumentMatchers.any[TagPartitionKeys]))
.thenReturn(Right(servicesTestEnv.questionTestEnv.tagPartitions))
doNothing().when(servicesTestEnv.mockPartitionsOfATagTransactionRepository).add(ArgumentMatchers.any[DistributedTransaction],ArgumentMatchers.any[TagPartitions],ArgumentMatchers.any[MutationCondition])
doNothing().when(servicesTestEnv.mockQuestionsCreatedByUserRepo).add(ArgumentMatchers.any[DistributedTransaction],ArgumentMatchers.any[QuestionsCreatedByAUserForATag],ArgumentMatchers.any[MutationCondition])
when(servicesTestEnv.mockUserProfileAndPortfolioTransactionRepository.get(ArgumentMatchers.any[DistributedTransaction],ArgumentMatchers.any[ExternalUserProfileKeys]))
.thenReturn(Right(servicesTestEnv.externalUserProfileWithTags))
doNothing().when(servicesTestEnv.mockUserProfileAndPortfolioTransactionRepository).update(ArgumentMatchers.any[DistributedTransaction],ArgumentMatchers.any[ExternalUserProfile])
doNothing().when(servicesTestEnv.mockDistributedTransaction).commit()
when(servicesTestEnv.mockSupportedTagsTransactionRepository.get(ArgumentMatchers.any[DistributedTransaction],ArgumentMatchers.any[SupportedTagsKeys]))
.thenReturn(Left(SupportedTagNotFoundException()))
val supportedTagInfo = SupportedTag("coding","javascript1","empty")
logger.trace(s"will compare with ${supportedTagInfo}")
val result = questionTransactionDBService.newQuestion(servicesTestEnv.questionTestEnv.practiceQuestion,servicesTestEnv.questionTestEnv.practiceQuestionTag,servicesTestEnv.user)
verify(servicesTestEnv.mockSupportedTagsTransactionRepository,times(0))
.add(servicesTestEnv.mockDistributedTransaction,supportedTagInfo)
}
如果我将 supportedTagInfo
的值更改为 val supportedTagInfo = SupportedTag("coding","javascript-something else","empty")
,测试用例仍然通过。
在痕迹中,我可以看到两次都使用了标签 coding-javascript-empty
。此值来自 servicesTestEnv.questionTestEnv.practiceQuestionTag
,这对两个测试用例都是通用的,并在
处提供
val result = questionTransactionDBService.newQuestion(servicesTestEnv.questionTestEnv.practiceQuestion,servicesTestEnv.questionTestEnv.practiceQuestionTag,servicesTestEnv.user)
TRACE - saving coding-javascript-empty in supported tag information
是我做错了什么还是 Mockito 没有检查参数值?
更新
我尝试在 Scala
中使用 ArgumentCaptor
但我很挣扎。
我创建了 class 的 mock
作为
val mockSupportedTagsTransactionRepository = mock(classOf[SupportedTagsTransactionRepository])
我正在调用 mock 的 add
方法。它的签名是
def add(transaction:DistributedTransaction,supportedTag:SupportedTag,mutationCondition:MutationCondition = new PutIfNotExists()) = {...}
我调用了上述模拟的 get
和 add
方法。我将他们的行为定义为
when(servicesTestEnv.mockSupportedTagsTransactionRepository.get(ArgumentMatchers.any[DistributedTransaction],ArgumentMatchers.any[SupportedTagsKeys]))
.thenReturn(Left(SupportedTagNotFoundException()))
然后我创建所需的 ArgumentCaptor
val argumentCaptor2 = ArgumentCaptor.forClass(classOf[SupportedTag])
val argumentCaptor3 = ArgumentCaptor.forClass(classOf[MutationCondition])
然后调用测试中的函数
verify(servicesTestEnv.mockSupportedTagsTransactionRepository ,times(1))
.add(argumentCaptor1.capture(),argumentCaptor2.capture(),argumentCaptor3.capture())
logger.trace(s"capture 1 ${argumentCaptor1.getAllValues}")
logger.trace(s"capture 2 ${argumentCaptor2.getAllValues}")
logger.trace(s"capture 3 ${argumentCaptor3.getAllValues}")
然后我查看结果
val argumentsInvoked = argumentCaptor2.getAllValues
argumentsInvoked.contains(supportedTagInfo)
必须为真
但是 argumentsInvoked
类型是 List[Nothing]
而不是 List[SupportedTag]
正确的方法是同时指定参数的类型
val argumentCaptor1 = ArgumentCaptor.forClass(classOf[DistributedTransaction])
val argumentCaptor2 = ArgumentCaptor.forClass[SupportedTag,SupportedTag](classOf[SupportedTag]) //Note two types. First is type of argument, second is type of class. They are the same in my case.
val argumentCaptor3 = ArgumentCaptor.forClass(classOf[MutationCondition])
verify(servicesTestEnv.mockSupportedTagsTransactionRepository ,times(1))
.add(argumentCaptor1.capture(),argumentCaptor2.capture(),argumentCaptor3.capture())
val argumentsInvoked = argumentCaptor2.getAllValues //this now returns List[SupportedTag]
argumentsInvoked.size mustBe 1
val argument = argumentsInvoked.get(0)
argument.course mustBe supportedTagInfo.course
argument.subject mustBe supportedTagInfo.subject
argument.topic mustBe supportedTagInfo.topic
在这个测试用例中,我想检查一个函数是否调用了特定的编号。具有特定值的次数
"add tag information in supported tags" in {
val servicesTestEnv = new ServicesTestEnv(components = components)
val questionTransactionDBService = new QuestionsTransactionDatabaseService(
servicesTestEnv.mockAnswersTransactionRepository,
servicesTestEnv.mockPartitionsOfATagTransactionRepository,
servicesTestEnv.mockPracticeQuestionsTagsTransactionRepository,
servicesTestEnv.mockPracticeQuestionsTransactionRepository,
servicesTestEnv.mockSupportedTagsTransactionRepository,
servicesTestEnv.mockUserProfileAndPortfolioTransactionRepository,
servicesTestEnv.mockQuestionsCreatedByUserRepo,
servicesTestEnv.mockTransactionService,
servicesTestEnv.mockPartitionsOfATagRepository,
servicesTestEnv.mockHelperMethods
)
when(servicesTestEnv.mockTransactionService.start)
.thenReturn(servicesTestEnv.mockDistributedTransaction)
doNothing().when(servicesTestEnv.mockPracticeQuestionsTransactionRepository).add(ArgumentMatchers.any[DistributedTransaction],ArgumentMatchers.any[PracticeQuestion],ArgumentMatchers.any[MutationCondition])
doNothing().when(servicesTestEnv.mockPracticeQuestionsTagsTransactionRepository).add(ArgumentMatchers.any[DistributedTransaction],ArgumentMatchers.any[PracticeQuestionTag],ArgumentMatchers.any[MutationCondition])
when(servicesTestEnv.mockPartitionsOfATagTransactionRepository.get(ArgumentMatchers.any[DistributedTransaction],ArgumentMatchers.any[TagPartitionKeys]))
.thenReturn(Right(servicesTestEnv.questionTestEnv.tagPartitions))
doNothing().when(servicesTestEnv.mockPartitionsOfATagTransactionRepository).add(ArgumentMatchers.any[DistributedTransaction],ArgumentMatchers.any[TagPartitions],ArgumentMatchers.any[MutationCondition])
doNothing().when(servicesTestEnv.mockQuestionsCreatedByUserRepo).add(ArgumentMatchers.any[DistributedTransaction],ArgumentMatchers.any[QuestionsCreatedByAUserForATag],ArgumentMatchers.any[MutationCondition])
when(servicesTestEnv.mockUserProfileAndPortfolioTransactionRepository.get(ArgumentMatchers.any[DistributedTransaction],ArgumentMatchers.any[ExternalUserProfileKeys]))
.thenReturn(Right(servicesTestEnv.externalUserProfileWithTags))
doNothing().when(servicesTestEnv.mockUserProfileAndPortfolioTransactionRepository).update(ArgumentMatchers.any[DistributedTransaction],ArgumentMatchers.any[ExternalUserProfile])
doNothing().when(servicesTestEnv.mockDistributedTransaction).commit()
when(servicesTestEnv.mockSupportedTagsTransactionRepository.get(ArgumentMatchers.any[DistributedTransaction],ArgumentMatchers.any[SupportedTagsKeys]))
.thenReturn(Left(SupportedTagNotFoundException()))
val supportedTagInfo = SupportedTag("coding","javascript1","empty")
logger.trace(s"will compare with ${supportedTagInfo}")
val result = questionTransactionDBService.newQuestion(servicesTestEnv.questionTestEnv.practiceQuestion,servicesTestEnv.questionTestEnv.practiceQuestionTag,servicesTestEnv.user)
verify(servicesTestEnv.mockSupportedTagsTransactionRepository,times(0))
.add(servicesTestEnv.mockDistributedTransaction,supportedTagInfo)
}
如果我将 supportedTagInfo
的值更改为 val supportedTagInfo = SupportedTag("coding","javascript-something else","empty")
,测试用例仍然通过。
在痕迹中,我可以看到两次都使用了标签 coding-javascript-empty
。此值来自 servicesTestEnv.questionTestEnv.practiceQuestionTag
,这对两个测试用例都是通用的,并在
val result = questionTransactionDBService.newQuestion(servicesTestEnv.questionTestEnv.practiceQuestion,servicesTestEnv.questionTestEnv.practiceQuestionTag,servicesTestEnv.user)
TRACE - saving coding-javascript-empty in supported tag information
是我做错了什么还是 Mockito 没有检查参数值?
更新
我尝试在 Scala
中使用 ArgumentCaptor
但我很挣扎。
我创建了 class 的 mock
作为
val mockSupportedTagsTransactionRepository = mock(classOf[SupportedTagsTransactionRepository])
我正在调用 mock 的 add
方法。它的签名是
def add(transaction:DistributedTransaction,supportedTag:SupportedTag,mutationCondition:MutationCondition = new PutIfNotExists()) = {...}
我调用了上述模拟的 get
和 add
方法。我将他们的行为定义为
when(servicesTestEnv.mockSupportedTagsTransactionRepository.get(ArgumentMatchers.any[DistributedTransaction],ArgumentMatchers.any[SupportedTagsKeys]))
.thenReturn(Left(SupportedTagNotFoundException()))
然后我创建所需的 ArgumentCaptor
val argumentCaptor2 = ArgumentCaptor.forClass(classOf[SupportedTag])
val argumentCaptor3 = ArgumentCaptor.forClass(classOf[MutationCondition])
然后调用测试中的函数
verify(servicesTestEnv.mockSupportedTagsTransactionRepository ,times(1))
.add(argumentCaptor1.capture(),argumentCaptor2.capture(),argumentCaptor3.capture())
logger.trace(s"capture 1 ${argumentCaptor1.getAllValues}")
logger.trace(s"capture 2 ${argumentCaptor2.getAllValues}")
logger.trace(s"capture 3 ${argumentCaptor3.getAllValues}")
然后我查看结果
val argumentsInvoked = argumentCaptor2.getAllValues
argumentsInvoked.contains(supportedTagInfo)
必须为真
但是 argumentsInvoked
类型是 List[Nothing]
而不是 List[SupportedTag]
正确的方法是同时指定参数的类型
val argumentCaptor1 = ArgumentCaptor.forClass(classOf[DistributedTransaction])
val argumentCaptor2 = ArgumentCaptor.forClass[SupportedTag,SupportedTag](classOf[SupportedTag]) //Note two types. First is type of argument, second is type of class. They are the same in my case.
val argumentCaptor3 = ArgumentCaptor.forClass(classOf[MutationCondition])
verify(servicesTestEnv.mockSupportedTagsTransactionRepository ,times(1))
.add(argumentCaptor1.capture(),argumentCaptor2.capture(),argumentCaptor3.capture())
val argumentsInvoked = argumentCaptor2.getAllValues //this now returns List[SupportedTag]
argumentsInvoked.size mustBe 1
val argument = argumentsInvoked.get(0)
argument.course mustBe supportedTagInfo.course
argument.subject mustBe supportedTagInfo.subject
argument.topic mustBe supportedTagInfo.topic