我想使用GoMock测试一些代码,而不是将测试与被测试对象的实际实现紧密地耦合在一起。但是GoMock似乎要求我能够提前说出被测试的代码将做什么,即使这不是我想要测试的契约的一部分。有办法绕道吗?
例如,假设我正在测试一些验证逻辑,测试中的代码需要接受名为Widget的mockedObject,如果mockedObject.CheckConditionA()或mockedObject.CheckCondition1()返回false,则返回false,否则返回true。一个正确的实施是:
func UnderTest(mockedObject *Widget) bool {
if !mockedObject.CheckConditionA() {
return false
}
return mockedObject.CheckCondition1()
}另一个是:
func UnderTest(mockedObject *Widget) bool {
if !mockedObject.CheckCondition1() {
return false
}
return mockedObject.CheckConditionA()
}第三个是:
func UnderTest(mockedObject *Widget) bool {
cA := mockedObject.CheckConditionA()
c1 := mockedObject.CheckCondition1()
return cA && c1
}第四个是:
func UnderTest(mockedObject *Widget) bool {
if TodayIsAnAlternateTuesday() {
return mockedObject.CheckCondition1() && mockedObject.CheckConditionA()
}
return mockedObject.CheckConditionA() && mockedObject.CheckCondition1()
}我的测试不应该关心其中的哪一个正在被使用,我只是想检查一下合同是否已经完成。
如何为这样的测试设置模拟,其中允许测试中的代码,但不需要调用方法?
对于CheckConditionA()将返回false的情况,我需要设置类似mockedObject.EXPECT().CheckConditionA().Return(false)的内容。但其中一些实现也需要一个mockedObject.EXPECT().CheckCondition1().Return(true)才能工作,否则我的测试将因意外调用而失败。另一方面,如果我提供那个EXPECT,由于缺少调用,有些会失败。
GoMock只是不支持编写这种测试吗?如果不是,我还能用什么来测试这个函数而不构建一个真实的Widget
发布于 2022-05-06 22:53:47
这个问题在一般的上下文中解决了这个问题,然后按照这个答案到这个答案显示,在这种情况下,您不需要 mocks ;您实际上想要Stubs,它们是不坚持被调用的模拟,但是如果调用它们将返回正确的东西。
GoMock自述文件实际上有关于构建存根而不是模拟的整个部分,其结果是您需要在EXPECT()调用链的末尾使用AnyTimes()使其成为可选的。
mockedObject.EXPECT().CheckConditionA().Return(false)
mockedObject.EXPECT().CheckCondition1().Return(true).AnyTimes()不幸的是,自述部分包含了一个标题和两个代码示例,没有关于存根是什么或者为什么有人想要存根的文本,这意味着如果您第一次接触基于模拟的测试是通过GoMock进行的,那么您将无法很快解决这个问题。主要的GoMock文档都有AnyTimes()的一行描述,但是没有关于存根的概念。(或者把嘲弄作为一种概念,他们只是假设你听说过它们。)
https://stackoverflow.com/questions/72148121
复制相似问题