验证在Mockito中运行的预期方法通常是这样的:
#include <stdio.h>
class Color
{
public:
Color(unsigned int _r, unsigned int _g, unsigned int _b, unsigned int _u, unsigned int _v) : r(_r), g(_g), b(_b), u(_u), v(_v) {}
unsigned int r, g, b, u, v;
static Color* getInstance (unsigned int _r, unsigned int _g, unsigned int _b, unsigned int _u, unsigned int _v);
};
Color* Color::getInstance(unsigned int _r, unsigned int _g, unsigned int _b, unsigned int _u, unsigned int _v)
{
return new Color(_r, _g, _b, _u, _v);
}
class Printer
{
public:
Printer() {}
~Printer() {}
static Printer* getInstance();
void print(Color *c);
};
Printer* Printer::getInstance()
{
return new Printer();
}
void Printer::print(Color *c)
{
printf("(%d, %d, %d, %d, %d)\n", c->r, c->g, c->b, c->u, c->v);
}
在创建模拟时,我有什么方法可以指定验证。在像EasyMock这样的东西我可以做:
when(mockFoo.someMethod()).thenReturn(someValue);
// run test
verify(mockFoo, times(n)).someMethod();
我的用例是我有一个常用的测试依赖项,我想模拟(doFooMethodAndReturnBar5Times模拟),但是对于Mockito,我没有办法对其强制执行验证。
答案 0 :(得分:4)
更新:此答案发生了重大变化,因为Mockito 2中提供了严格的模拟,默认情况下Mockito 3中可以使用严格存根的强制执行。使用strict
和{{ 1}}模式来配置这些模拟和存根,并查看mockito issue 769以获取文档和进度。
在Mockito 2之前,这不是Mockito可以轻易做到的事情。 EasyMock的默认严格模拟确保(1)意外交互立即失败,(2)所有预期的交互发生;除了lenient
之外,Mockito还没有设置任何设置(它不会立即失败,而是在测试结束时)。这是philosophical design decision on Mockito's part,请参阅this thread Mockito发起人进一步讨论的内容。
事实上,Mockito的verifyNoMoreInteractions
语法取决于它允许意外的互动,因为意外的互动告诉Mockito调用了哪种方法:
when
容忍意外电话的EasyMock模拟被称为“漂亮的模拟”; Mockito的一大卖点是默认情况下模拟很好,因此它们通常容忍与被测试行为无关的调用。这确实使调试变得更加困难,因为Mockito不会像EasyMock那样立即在意外的交互中失败,但它也会使测试变得不那么脆弱 - 因为EasyMock模拟,安全更改更可能会破坏测试得到一个意外的电话。 在继续之前,请与您的团队确认他们会对您的选择感到满意:严格的模拟语义对于Mockito来说是相对较新的而且可能会有很大的假设作为框架变革的交易。 (到那时,在看到替代方案后,他们可能会让你使用EasyMock!)
要在Mockito 2 +中使用严格的模拟,,请参阅syntax and libraries in Mockito issue 769。这可能是从Mockito 1.x升级的一个很好的理由。
要在Mockito 1.x中模拟严格的模拟,您需要设置一个未通过测试的默认答案,并且仅使用when(mockFoo.someMethod()).thenReturn(someValue);
// ^^^^^^^^^^^^^^^^^^^^ Java calls this first to get an argument for when,
// which is how Mockito knows which method to stub:
// it's always the last one called.
方法建立正确的行为({ {1}},doVerb
,doAnswer
等)。此语法为Mockito提供了停用存根行为所需的警告。要创建默认答案,您可以为单个方法设置行为(首选),也可以为单个模拟设置所有方法。
doReturn
Mockito将始终在最后定义的匹配链上返回行为,并且仅在没有链匹配时才使用默认答案,因此您应该能够使用doThrow
方法定义任意数量的链来覆盖该行为