62

我正在我的公司开展单元测试工作,需要选择一个模拟框架来使用。我以前从未使用过模拟框架。我们已经选择了 Google Test,所以使用 Google Mock 会很好。不过,看了Google Mock 的教程后,我的初步印象是:

  • 使用 MOCK_METHODn 宏重新声明模拟类中的每个方法似乎没有必要,而且似乎违背了 DRY 原则。
  • 它们的匹配器(例如,EXPECT_CALL(turtle, Forward(_)); 中的“_”)和匹配顺序似乎太强大了。就像,很容易说出你不是故意的话,这样会错过错误。

我对 google 的开发者有很高的信心,对自己判断 mocking 框架的能力信心不足,之前没用过。所以我的问题是:这些是有效的担忧吗?

或者没有更好的方法来定义模拟对象,并且匹配器在实践中使用起来是否直观?我会感谢任何以前使用过 Google Mock 的人的回答,并且与其他 C++ 框架进行比较会有所帮助。

4

4 回答 4

45

我经常使用它。

做相对简单的事情是微不足道的,并且可能做非常困难的事情——这几乎是我想要从框架中得到的。

使用 Google 的 mock 编写自定义 Matchers(和其他东西)最困难的部分不是 Google 的 mock,而是 C++ 的模板错误......它们几乎无法解析。我经常通过从一些不太复杂的表达式逐步构建一个工作表达式来编写复杂的表达式。这样,模板错误更容易查明。

我还没有看到 C++ 模拟的更好选择,而且 Google 涵盖了很多领域,所以我建议你试一试。

WRT DRY 原则,我同意声明模拟方法是不幸的,但是如果没有反思,我不确定 c++ 会不会有很多运气。我几乎可以肯定,如果有办法,googlemock 会使用它;)

顺便说一句:googlemock 食谱是一个很好的参考。

于 2010-05-13T14:04:08.080 回答
23

Fake-It是一个简单的 C++ 模拟框架。FakeIt 使用最新的 C++11 特性来创建一个富有表现力(但非常简单)的 API。使用 FakeIt,无需重新声明方法,也无需为每个模拟创建派生类。这是你如何伪造它:

struct SomeInterface {
  virtual int foo(int) = 0;
};

// That's all you have to do to create a mock.
Mock<SomeInterface> mock; 

// Stub method mock.foo(any argument) to return 1.
When(Method(mock,foo)).Return(1);

// Fetch the SomeInterface instance from the mock.
SomeInterface &i = mock.get();

// Will print "1"
cout << i.foo(10);

还有更多功能需要探索。来吧,试一试

于 2014-09-09T07:04:17.550 回答
15

免责声明:我写了 HippoMocks。

我可以推荐查看其他模拟框架;其中有一类不会让你重复自己。它们还取消了用于匹配的新语法,使您的代码读起来更像是 C++ 与英语的结合。试试看!

http://www.assembla.com/wiki/show/hippomocks

于 2010-05-18T13:44:55.580 回答
9

几年来,我一直在专业地使用 googletest + googlemock,我绝对喜欢它。其他人没有提到的一件事是,如果您已经致力于使用 googletest,那么使用 googlemock 也很有意义。它们整合得相当好,并且共享相似的设计风格和理念,这很好。

例如,googlemock 提供了ASSERT_THAT()超级有用的宏,并且与 googletests 的断言很好地共存。

但是,我会警告您不要滥用 googlemock 的功能。编写非常复杂且功能强大的匹配器可能非常诱人,但最终完全不可读。您只需要在使用它时遵守纪律。

其他一些想法:

  • Googlemock 的学习曲线可能有些陡峭;匹配器和期望的复杂性并不像您希望的那样直截了当。
  • 关于违反 DRY 的担忧是有道理的;当看起来可以很容易地自动生成模拟时,不得不手动定义模拟是很烦人的。团队编写自己的代码生成器来为他们的接口自动定义 googlemocks 是很常见的。
于 2014-12-15T19:46:58.867 回答