假设我们有一个单元测试,它首先执行一个我们希望函数someFunc不会被调用的代码序列,然后执行一个我们期望该函数只被调用一次的代码序列。使用HippoMocks,我们可以这样写它:
#include <hippomocks.h>
void someFunc (void)
{
}
int main (int argc, char ** argv)
{
MockRepository mocks;
mocks.autoExpect = false;
mocks.NeverCallFunc(someFunc); // line 27
/* some testing code ... */
/* ... in the course of which someFunc does not get called ... */
mocks.ExpectCallFunc(someFunc); // line 33
/* other testing code ... */
someFunc();
/* ... in the course of which someFunc got called */
return 0;
}但是,当在Windows上运行上面的代码片段(用Cygwin工具链编译)时,会抛出一个HippoMocks::ExpectationException:
terminate called after throwing an instance of 'HippoMocks::ExpectationException'
what(): Function someFunc() called with mismatching expectation!
Expectations set:
../main.cpp(33) Expectation for someFunc() on the mock at 0x0 was not satisfied.
Functions explicitly expected to not be called:
../main.cpp(27) Result set for someFunc() on the mock at 0x0 was used.所以我想知道...
... (1),如果HippoMocks不是为处理这种情况而设计的。期望someFunc被调用(第33行)不会替换相应模拟存储库中之前的期望吗?
... (2),为什么第二个期望(第33行)没有满足,因为someFunc被显式地调用。如果有的话,我会期望第一个期望(第27行)没有得到满足?
有趣的是,事情正好相反。以下代码段运行时没有任何问题:
#include <hippomocks.h>
void someFunc (void)
{
}
int main (int argc, char ** argv)
{
MockRepository mocks;
mocks.autoExpect = false;
mocks.ExpectCallFunc(someFunc); // line 27
/* some testing code ... */
someFunc();
/* ... in the course of which someFunc got called */
mocks.NeverCallFunc(someFunc); // line 33
/* other testing code ... */
/* ... in the course of which someFunc does not get called ... */
/* someFunc(); */
return 0;
}此外,如果在第二个代码片段中的第二个期望之后插入对someFunc的调用(如注释中所示),则HippoMocks会检测到这一点,并将其报告为“从不调用”期望,正如人们所预期的那样:
terminate called after throwing an instance of 'HippoMocks::ExpectationException'
what(): Function someFunc() called with mismatching expectation!
Expectations set:
../main.cpp(27) Expectation for someFunc() on the mock at 0x0 was satisfied.
Functions explicitly expected to not be called:
../main.cpp(33) Result set for someFunc() on the mock at 0x0 was used.任何HippoMocks专家的帮助都将不胜感激。
发布于 2017-02-06 21:05:36
NeverCall和ExpectCall之间的交互以前没有真正考虑过--我从来没有期望人们使用NeverCall太多,所以我没有意识到这种交互作用。
在当前发布的版本中,NeverCall将在以前的ExpectCall上获得autoexpect,并且所有NeverCall都将首先被检查。这将导致ExpectCall/NeverCall按预期工作-即,您首先获得expect,然后NeverCall处于活动状态。在NeverCall/ExpectCall的情况下,不添加autoexpect,并且NeverCall获得优先级。这是违反直觉的,我认为最好是交换行为,以便ExpectCalls始终获得优先级,如果它们可以匹配的话。
我已经将您的示例添加为新的测试用例&交换了NeverCall和ExpectCall的匹配顺序。我还删除了NeverCalls的autoExpect -因为它一开始就不应该出现在那里。结果是,您的两个示例现在都将以您期望的方式工作,无论是打开还是关闭autoExpect。如果someCall在NeverCall设置之后,您的第二个示例也可以工作。这允许您比以前更多地对设置代码进行分组。
如果您想测试/切换到这个版本,请注意它仍然在cpp11分支上。当确认分支稳定并且文档适当扩展时,我会将其合并到master & release。目前它没有任何已知的问题。它在Github:https://github.com/dascandy/hippomocks/tree/cpp11上。
发布于 2016-07-29 16:28:12
您不能这样做,因为NeverCall旨在为断言抛出异常。对我来说似乎完全不合逻辑。
如果您真的想解决这个问题,请设置以下内容
mocks.OnCallFunc(someFunc).Do(someFuncCalledHandler);在您自己的处理程序中,您可以实现所需的逻辑:
bool callAllowed = true; //global variable
void someFuncCalledHandler()
{
if (!callAllowed)
{
throw MyNeverCallException();
}
}在您的测试中,您可以控制someFuncCalledHandler()的行为:
callAllowed = false;
someFunc();顺便说一句:在测试中混合排列和动作代码不是一个好主意,就像您在示例代码中所做的那样
发布于 2016-09-09 19:56:13
当调用MockRepository的析构函数或显式调用其VerifyAll()方法时,将检查Hippomock期望。在第33行之前调用VerifyAll(),第一个示例将正常工作。
我赞同前面的答案,即测试代码和测试代码不应该混淆,但我可以想象这只是为了一个紧凑的问题。
https://stackoverflow.com/questions/38033770
复制相似问题