【发布时间】:2020-09-04 16:28:20
【问题描述】:
在这个测试用例中,我想检查一个函数是否被称为特定编号。具有特定值的次数
"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,但我很挣扎。
我已经创建了mock这个类
val mockSupportedTagsTransactionRepository = mock(classOf[SupportedTagsTransactionRepository])
我正在调用模拟的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]
【问题讨论】:
-
Mockito 会检查参数值。问题必须在您的代码中的其他地方。
-
你没有使用正确的验证来捕获 var,你可以改进一点代码,我会更具体地展示你需要的东西,我可以尝试使用参数捕获器但是我无法得到你的 var 模拟或你的代码结构是什么
-
@MarcoPens - 谢谢。我已经添加了完整的规范。