Google C++单元测量检验框架谷歌Test—Google Mock简要介绍–概念及底子语法,javamock框架

就在昨日终究做了gtest的分享,小编的预备性研商专门的工作终于终止了,以为离本人辞职的小日子不远了,究竟是静心java二百多年啊,要拜别实习啦。。

这篇是GoogleMock的简单介绍文书档案,会在后边附带一个和煦的例证。

一、什么是Google C ++ Mocking Framework?

   当你写三个原型或测验,往往不可能一心的信赖真实对象。八个mock对象达成与二个实在对象相仿的接口,但令你在运转时钦赐它时,怎么样使用?它应有做如何?(哪些措施将被称之为?什么顺序?多少次?有啥参数?他们会回去什么?等卡塔 尔(英语:State of Qatar)

只顾:十分轻易模糊伪造对象和模仿指标。fakes和mock在测验驱动开拓(TDD卡塔尔国社区中其实意味着特别不一致的事物:

  • Fake(伪对象卡塔 尔(英语:State of Qatar)有专门的职业落实,但冷眼观察选用部分捷径(或者使操作更方便人民群众卡塔尔,那使得它们不适合生育。内部存款和储蓄器中的文件系统将是七个fake的例证。
  • Mock(模拟器卡塔尔国是预料编制程序的对象,它们变成它们希望接收的调用的正式。

举例具有那个对你的话太肤浅了,不要操心 –
最根本的职业要铭记在心是二个模拟允许你检查它和睦剂调用者之间的人机联作。黄金年代旦您起头运用mock,fake和mock之间的不同将变得更其清楚。

Google C ++ Mocking框架(或简称为谷歌(Google卡塔 尔(英语:State of Qatar)Mock卡塔尔是二个库(有的时候大家誉为“框架”,以使其声音非常的帅卡塔尔国用于创造模拟类和使用它们。
它之对于对C ++,就疑似jMock和EasyMock对于Java。

运用谷歌(Google卡塔 尔(阿拉伯语:قطر‎ Mock涉及多个为主步骤:

  1. 使用部分简练的宏描述你想要模拟的接口,他们将扩充到您的mock类的得以完成;
  2. 创办一些效仿指标,并行使直观的语法钦赐其愿意和行事;
  3. 持始终如一使用模拟目的的代码。 GoogleMock会在现身其余违背期待的场馆时及时管理。

一、什么是Google C ++ Mocking Framework?

 
 当你写一个原型或测量检验,往往不可能一心的借助真实对象。叁个mock对象实现与二个真真对象相同的接口,但令你在运行时钦命它时,怎样行使?它应当作怎么样?(哪些措施将被称为?什么顺序?多少次?有如何参数?他们会回去什么?等卡塔 尔(阿拉伯语:قطر‎

小心:非常轻便指皁为白杜撰对象和模仿目的。fakes和mock在测试驱动开垦(TDD卡塔尔社区中实际意味着很分歧的事物:

  • Fake(伪对象卡塔 尔(英语:State of Qatar)有专门的学问完成,但日常采取一些近便的小路(可能使操作更方便卡塔 尔(英语:State of Qatar),那使得它们不相符生育。内部存款和储蓄器中的文件系统将是三个fake的事例。
  • Mock(模拟器卡塔 尔(阿拉伯语:قطر‎是预期编制程序的目的,它们变成它们希望接纳的调用的正经。

例如持有那些对您来讲太肤浅了,不要忧郁 –
最首要的事情要深深记住是三个效仿允许你检查它协调理调用者之间的并行。意气风发旦你从头采纳mock,fake和mock之间的歧异将变得越来越清晰。

谷歌 C ++ Mocking框架(或简单的称呼为GoogleMock卡塔 尔(阿拉伯语:قطر‎是八个库(偶尔大家称为“框架”,以使其声音很帅卡塔尔国用于创制模拟类和选拔它们。
它之对于对C ++,就好像jMock和EasyMock对于Java。

选拔Google Mock涉及多个大旨步骤:

二、为啥选取谷歌(Google卡塔 尔(英语:State of Qatar) Mock?

  即便模拟指标能够援助你剔除测量试验中不供给的信赖性,并使它们不慢可信赖,在C
++中手动使用mock是很难的:

  • 有人必得达成Mock。这些工作一般很枯燥,轻巧出错。难怪大家走相当的远的间距,防止它。
  • 这一个手动写的Mock的品质微微,呃,不可预测。你大概会看出有个别真正抛光的,但你也说不许见到局地被匆忙的侵扰,并有丰盛多采的有时间约束制。
  • 您从利用四个效仿得到的学识不会调换来下一个。

相比较,Java和Python技师有风姿罗曼蒂克对英俊的依葫芦画瓢框架,自动成立mock。由此,Mock是生机勃勃种被注解是实用的才干,并在这里些社区科学普及通机械化采煤用的做法。具有不错的工具相对有所区别。

Google Mock意在救助C
++程序猿。它的灵感来源jMock和EasyMock,不过设计时构思了C
++的底细。假使下列任何难点找麻烦你会很有扶持:

  • 你的测量检验一点也不快,因为它们依据于太多的库或选取昂贵的能源(举个例子数据库卡塔尔。
  • 您的测量检验是虚亏的,因为他们接受的片段能源是不可信赖的(比方互连网卡塔尔。
  • 您想要测量检验代码如什么地方理战败(举例,文件校验和谬误卡塔 尔(英语:State of Qatar),但不易于造成。
  • 您供给确定保障您的模块以科学的不二等秘书籍与任何模块交互作用,可是很难旁观到互相;由此你诉诸于旁观行动甘休时的副成效,那是最狼狈的。
  • 你想“模拟出”你的信任,除了他俩尚无模拟实现;坦白地说,你对那个手写的笑话并不倍感快乐。

小编们提议你使用Google Mock:

二个企划工具,它能够令你早日寻常尝试你的分界面设计。越多的迭代以致越来越好的打算!
三个测量试验工具,用于私分测量试验的出站信赖关系,并探测模块与其协笔者之间的并行。

二、为啥选取谷歌(Google卡塔尔 Mock?

  就算模拟目的能够扶植您剔除测量试验中无需的借助,并使它们异常的快靠谱,在C
++中手动使用mock是很难的:

  • 有人必需完结Mock。那个专门的学业平常很干燥,轻便失误。难怪人们走非常远的离开,幸免它。
  • 那几个手动写的Mock的质量稍稍,呃,不可预测。你或许会看见有的真的抛光的,但您也可能见到局地被匆忙的骚扰,并有各种各样的临时间限定制。
  • 你从使用一个仿照得到的文化不会转移到下三个。

对照,Java和Python程序猿有意气风发对Mini的模仿框架,自动成立mock。因而,Mock是风姿罗曼蒂克种被验证是卓有效用的本事,并在此些社区广大采纳的做法。具备无可争论的工具相对有所不相同。

Google Mock目的在于救助C
++技术员。它的灵感来源于jMock和EasyMock,可是设计时思考了C
++的细节。尽管下列任何难点苦恼你会很有赞助:

  • 您的测量试验不快,因为它们依附于太多的库或使用昂贵的财富(比如数据库卡塔尔。
  • 你的测量检验是薄弱的,因为她们接纳的某个财富是不可信赖的(举例互联网卡塔 尔(英语:State of Qatar)。
  • 您想要测量试验代码如哪个地点理失利(举例,文件校验和不当卡塔 尔(英语:State of Qatar),但不轻便以致。
  • 你须要确定保障您的模块以科学的章程与任何模块交互作用,但是很难观望到相互;由此你诉诸于观看行动甘休时的副成效,那是最为难的。
  • 您想“模拟出”你的注重,除了他们不曾模拟完毕;坦白地说,你对这么些手写的耻笑并不认为欢娱。

咱俩提出您使用谷歌 Mock:

三个企划工具,它能够让您早日常常尝试你的分界面设计。更多的迭代引致越来越好的兼备!
叁个测量试验工具,用于私分测验的出站正视关系,并探测模块与其协作者之间的相互。

三、入门

运用Google Mock非常轻巧! 在您的C ++源文件中,只要#include“gtest /
gtest.h”和“gmock / gmock.h”,你曾经筹算好了。

三、入门

运用谷歌(Google卡塔 尔(英语:State of Qatar) Mock超轻松! 在你的C ++源文件中,只要#include“gtest /
gtest.h”和“gmock / gmock.h”,你已经打算好了。

四、一个Mock Turtles的案例

让我们看叁个例证。 假若您正在开采一个依据LOGO的API来绘图的图纸程序。
你将如何测量检验它做精确的政工?
好呢,你能够运作它,并将显示屏与鲜绿显示屏快速照相,比较显示屏,但让我们明确:那样的测量试验运转和虚弱昂贵(假设你刚刚进级到三个闪耀的新显卡有越来越好的抗锯齿?猛然你不得不立异具有的黄金图像。卡塔 尔(阿拉伯语:قطر‎。
假诺持有的测量试验都以那般的,那将是太优伤了。
幸运的是,你学习了正视注入,并且了然科学的作业:不是让应用程序直接与绘图API交互作用,而是将API封装在叁个接口(例如,Turtle卡塔尔国中,并用代码编写翻译该接口:

1
2
3
4
5
6
7
8
9
10
11
class Turtle {
  ...
  virtual ~Turtle() {}
  virtual void PenUp() = 0;
  virtual void PenDown() = 0;
  virtual void Forward(int distance) = 0;
  virtual void Turn(int degrees) = 0;
  virtual void GoTo(int x, int y) = 0;
  virtual int GetX() const = 0;
  virtual int GetY() const = 0;
};

(注意,Turtle的析构函数必须是假造的,就好像您思量一而再三番五次的全数类的情形相似 –
不然当通过骨干指针删除三个目的时,派生类的析构函数不会被调用,你会赢得损坏的前后相继状态,如内部存款和储蓄器泄漏。卡塔尔

你能够采纳PenUp(卡塔尔和PenDown(卡塔尔调节turtle的移位是不是留下轨迹,并运用Forward(卡塔 尔(英语:State of Qatar),Turn(卡塔尔和GoTo(卡塔尔国调控其运动。最终,GetX(卡塔 尔(英语:State of Qatar)和GetY(卡塔尔国告诉你最近任务的turtle。

您的顺序平常会使用这么些接口的骨子里得以实现。在测量检验中,您能够采用模拟完结。那允许你轻易地检讨你的次第正在调用什么绘图基元,有哪些参数,甚至各样。以这种格局编写的测验越来越强盛,更便于读取和保安(测量试验的用意表示在代码中,并不是在一些二进制图像中卡塔 尔(英语:State of Qatar)运营得多,快得多。

四、一个Mock Turtles的案例

让大家看二个例证。 要是您正在开辟三个依照LOGO的API来绘图的图片程序。
你将何以测验它做科学的专门的学业?
可以吗,你能够运维它,并将荧屏与群青显示器快速照相,比较显示器,但让大家认同:那样的测量检验运营和虚弱昂贵(借使您刚刚进级到叁个闪光的新显卡有越来越好的抗锯齿?溘然你一定要改过具备的白金图像。卡塔 尔(阿拉伯语:قطر‎。
假设具备的测量检验都以如此的,那将是太痛楚了。
幸运的是,你学习了重视注入,而且精晓科学的业务:不是让应用程序直接与绘图API人机联作,而是将API封装在多少个接口(比如,Turtle卡塔尔国中,并用代码编写翻译该接口:

class Turtle {
  ...
  virtual ~Turtle() {}
  virtual void PenUp() = 0;
  virtual void PenDown() = 0;
  virtual void Forward(int distance) = 0;
  virtual void Turn(int degrees) = 0;
  virtual void GoTo(int x, int y) = 0;
  virtual int GetX() const = 0;
  virtual int GetY() const = 0;
};

(注意,Turtle的析构函数必得是编造的,就疑似你筹算一连的全部类的景况亦然 –
不然当通过骨干指针删除叁个对象时,派生类的析构函数不会被调用,你会博得损坏的程序状态,如内部存款和储蓄器泄漏。卡塔 尔(英语:State of Qatar)

您能够利用PenUp(卡塔 尔(英语:State of Qatar)和PenDown(卡塔 尔(英语:State of Qatar)调整turtle的位移是还是不是留下轨迹,并选用Forward(卡塔尔,Turn(卡塔尔国和GoTo(卡塔 尔(英语:State of Qatar)调控其运动。最终,GetX(卡塔尔国和GetY()告诉您眼下地点的turtle。

你的次序日常会动用这些接口的实在落到实处。在测量试验中,您能够动用模拟落成。这允许你轻便地检讨你的前后相继正在调用什么绘图基元,有什么参数,以致各样。以这种措施编写的测验更有力,更易于读取和掩护(测验的盘算表示在代码中,实际不是在有的二进制图像中卡塔尔国运转得多,快得多。

五、编写模拟类

如果你好运,你供给选拔的mock已经被部分好的人达成。可是,你发现自身在写一个仿照class,放松-
谷歌 Mock将以此职务产生贰个美不可言的玩耍! (嗯,大约。卡塔尔

五、编写模拟类

若果你恰巧,你须求动用的mock已经被一些好的人完结。然则,你开掘自个儿在写多少个模拟class,放松-
谷歌 Mock将以此职责变成一个幽默的玩乐! (嗯,大概。卡塔 尔(阿拉伯语:قطر‎

1. 哪些定义它

应用Turtle分界面作为示范,以下是你需求坚决守住的简约步骤:

  1. 从Turtle派生三个类MockTurtle。
  2. 使用Turtle的虚函数(即便能够应用模板来模拟非虚方法,不过它越来越多的关系卡塔 尔(英语:State of Qatar)。总结它有个别许参数。
  3. 在子类的public:部分,写MOCK_METHODn();
    (或MOCK_CONST_METHODn(卡塔 尔(英语:State of Qatar);尽管您是二个const方法卡塔 尔(阿拉伯语:قطر‎,个中n是参数的数额;如若你计数错误,产生一个多少个编写翻译器错误:shame
    on you 。
  4. 今昔赶来有意思的一些:你使用函数签字,剪切和粘贴函数名作为宏的率先个参数,并留住左侧的第二个参数(如若你感叹,那是类其余作用卡塔尔国。
  5. 再一次,直到你要效仿的具备虚构功用完毕。

After the process, you should have something like:

1
2
3
4
5
6
7
8
9
10
11
12
#include "gmock/gmock.h"  // Brings in Google Mock.
class MockTurtle : public Turtle {
 public:
  ...
  MOCK_METHOD0(PenUp, void());
  MOCK_METHOD0(PenDown, void());
  MOCK_METHOD1(Forward, void(int distance));
  MOCK_METHOD1(Turn, void(int degrees));
  MOCK_METHOD2(GoTo, void(int x, int y));
  MOCK_CONST_METHOD0(GetX, int());
  MOCK_CONST_METHOD0(GetY, int());
};

您不必要在别的地点定义那么些模拟方法 – MOCK_METHOD *宏将为您生成定义。
正是如此轻巧! Once you get the hang of it, you can pump out mock
classes faster than your source-control system can handle your
check-ins。

晋升:尽管那样做对你的话太多了,你会开掘谷歌(Google卡塔 尔(英语:State of Qatar) Mock的scripts / generator
/目录(由cppclean项目提供卡塔尔中的gmock_gen.py工具很有用。
那一个命令行工具须求你安装Python 2.4。 你给它三个C
++文件和它定义的抽象类的称呼,它将为你打字与印刷模拟类的定义。 由于C
++语言的复杂性,那几个本子也许不一而再连续职业,但它可以很有利。
有关越来越多详细新闻,请阅读 user
documentation。 

1. 怎么定义它

运用Turtle界面作为示范,以下是您需求根据的轻松步骤:

After the process, you should have something like:

#include "gmock/gmock.h"  // Brings in Google Mock.
class MockTurtle : public Turtle {
 public:
  ...
  MOCK_METHOD0(PenUp, void());
  MOCK_METHOD0(PenDown, void());
  MOCK_METHOD1(Forward, void(int distance));
  MOCK_METHOD1(Turn, void(int degrees));
  MOCK_METHOD2(GoTo, void(int x, int y));
  MOCK_CONST_METHOD0(GetX, int());
  MOCK_CONST_METHOD0(GetY, int());
}; 

你没有须要在其它市方定义这一个模拟方法 – MOCK_METHOD *宏将为你生成定义。
正是这么轻易! Once you get the hang of it, you can pump out mock
classes faster than your source-control system can handle your
check-ins。

提醒:纵然如此做对您的话太多了,你会意识Google Mock的scripts / generator
/目录(由cppclean项目提供卡塔 尔(阿拉伯语:قطر‎中的gmock_gen.py工具很有用。
那个命令行工具须求您安装Python 2.4。 你给它三个C
++文件和它定义的抽象类的称呼,它将为您打字与印刷模拟类的概念。 由于C
++语言的复杂,那么些剧本大概不再而三职业,但它能够很有益。
有关更加多详细信息,请阅读 user documentation。 

2. 在何地放

当你定义三个mock类,你必要调节在哪个地方放置它的概念。有些人把它座落一个*
_test.cc。当被mock的接口(举个例子,Foo卡塔尔由同一人或团队有着时,那是很好的。不然,当Foo的持有者改造它,你的测验也许会中断。
(你不可能确实愿意Foo的维护者修复利用Foo的各类测量检验,你能吧?卡塔尔国

于是,经历法规是:如若你供给效法Foo并且它由其余人颇负,在Foo的包中定义模拟类(越来越好的是,在三个测验子包中,你能够知晓地分离临蓐代码和测量试验实用程序卡塔尔国,并且把它位于mock_foo.h。然后每种人都得以从它们的测验引用mock_foo.h。假如Foo变化,只有多少个MockFoo的别本要改造,独有依附于校正的方法的测量检验需求修补。

另风度翩翩种艺术:你能够在Foo的最上部引进五个薄层FooAdaptor,并将代码引入那几个新的接口。由于你有所FooAdaptor,你能够更便于地收取Foo的变化。纵然那是前期的行事,细心采纳适配器接口能够使您的代码更易于编写和越发可读性,因为您还行FooAdaptor相符您的一定领域比Foo更加好。

2. 在哪儿放

当您定义贰个mock类,你需求调控在哪儿放置它的定义。有些人把它放在一个*
_test.cc。当被mock的接口(比方,Foo卡塔尔由同一位或协会有着时,那是很好的。不然,当Foo的全体者改造它,你的测量试验恐怕会一曝十寒。
(你不能够确实希望Foo的跟随者修复应用Foo的各样测量试验,你能啊?卡塔尔国

进而,经验准则是:假设您须要效法Foo而且它由其余人颇负,在Foo的包中定义模拟类(越来越好的是,在一个测量试验子包中,你能够领略地分开生产代码和测量检验实用程序卡塔尔,并且把它身处mock_foo.h。然后每一种人都可以从它们的测量检验援用mock_foo.h。如若Foo变化,独有三个MockFoo的别本要转移,独有注重于纠正的艺术的测量检验须要修补。

另风流倜傥种艺术:你能够在Foo的最上端引入多个薄层FooAdaptor,并将代码引入那一个新的接口。由于你具备FooAdaptor,你能够更便于地接过Foo的变化。尽管那是开始的生龙活虎段时代的事业,留意选拔适配器接口能够使您的代码更易于编写和特别可读性,因为你能够筛选FooAdaptor符合您的一定领域比Foo越来越好。

六、在测量检验中利用模拟器

若是您有三个模拟类,使用它十分轻松。 规范的职业流程是:

  1. 从测验命名空间导入GoogleMock名称,以便你能够接纳它们(每一种文件只需进行三遍。请记住,命名空间是一个好主意,有支持您的健康。卡塔尔
  2. 一个mock对象实现与一个真实对象相同的接口,就在昨天终于做了gtest的分享威尼斯人平台。创建一些效仿目的。
  3. 点名你对它们的希望(贰个主意被调用多少次?有如何参数?它应该做哪些等等卡塔尔。
  4. 练习一些运用mock的代码; 能够利用GoogleTest断言检查结果。假使二个mock方法被调用超越预期或错误的参数,你会马上获得贰个八花九裂。
  5. 当模拟碰着破坏时,Google Mock将活动检查是还是不是知足了对其的装有十分大希望。

那边有多个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include "path/to/mock-turtle.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
using ::testing::AtLeast;                     // #1
 
TEST(PainterTest, CanDrawSomething) {
  MockTurtle turtle;                          // #2
  EXPECT_CALL(turtle, PenDown())              // #3
      .Times(AtLeast(1));
 
  Painter painter(&turtle);                   // #4
 
  EXPECT_TRUE(painter.DrawCircle(0, 0, 10));
}                                             // #5
 
int main(int argc, char** argv) {
  // The following line must be executed to initialize Google Mock
  // (and Google Test) before running the tests.
  ::testing::InitGoogleMock(&argc, argv);
  return RUN_ALL_TESTS();
}

正如你可能曾经猜到的,那个测量试验检查PenDown(卡塔 尔(阿拉伯语:قطر‎被调用最少三遍。
假若painter对象没有调用此形式,您的测验将停业,并出示如下音信:

path/to/my_test.cc:119: Failure
Actual function call count doesn't match this expectation:
Actually: never called;
Expected: called at least once.

唤醒1:尽管从Emacs缓冲区运转测验,您可以在错误消息中呈现的行号上按<Enter>,间接跳到停业的料想。

提示2:即使您的依葫芦画瓢指标一向未有被删除,最后的证实不会发出。由此,当您在堆上分配mock时,在测验中利用堆泄漏检查器是个好主意。

驷不及舌提示:谷歌Mock须求在调用mock函数以前安装期待值,不然行为是未定义的。非常是,你无法交错EXPECT_CALL()和调用mock函数。

那意味着EXPECT_CALL(卡塔 尔(阿拉伯语:قطر‎应该被读取为期待call将要未来产生,而不是call已经产生。为啥GoogleMock会那样工作?好的,事先指按期望允许GoogleMock在上下文(旅社追踪等卡塔 尔(英语:State of Qatar)如故可用时马上告知违例。那使得调节和测验更易于。

真的,这么些测验是两全的,未有做太多。您能够轻便达成均等的效应,而没有须求使用谷歌(Google卡塔 尔(阿拉伯语:قطر‎Mock。然则,正如我们将急速公布的,谷歌(Google卡塔尔宪章允许你做更加多的mock。

六、在测验中应用模拟器

尽管你有一个模拟类,使用它超级轻松。 规范的办事流程是:

这里有二个例证:

#include "path/to/mock-turtle.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
using ::testing::AtLeast;                     // #1

TEST(PainterTest, CanDrawSomething) {
  MockTurtle turtle;                          // #2
  EXPECT_CALL(turtle, PenDown())              // #3
      .Times(AtLeast(1));

  Painter painter(&turtle);                   // #4

  EXPECT_TRUE(painter.DrawCircle(0, 0, 10));
}                                             // #5

int main(int argc, char** argv) {
  // The following line must be executed to initialize Google Mock
  // (and Google Test) before running the tests.
  ::testing::InitGoogleMock(&argc, argv);
  return RUN_ALL_TESTS();
}

正如您也许早已猜到的,这些测量试验检查PenDown(卡塔 尔(英语:State of Qatar)被调用起码二回。
假使painter对象未有调用此办法,您的测量试验将失败,并显示如下信息:

path/to/my_test.cc:119: Failure
Actual function call count doesn't match this expectation:
Actually: never called;
Expected: called at least once.

提拔1:假诺从Emacs缓冲区运营测量检验,您可以在错误信息中显示的行号上按<Enter>,直接跳到停业的意料。

提醒2:如若你的模拟指标平昔未有被删去,最终的印证不会发生。由此,当你在堆上分配mock时,在测试中央银行使堆泄漏检查器是个好主意。

器重提示:GoogleMock必要在调用mock函数此前安装期待值,不然行为是未定义的。极其是,你不能够交错EXPECT_CALL()和调用mock函数。

那意味着EXPECT_CALL(卡塔尔国应该被读取为期待call将在未来时有爆发,并非call已经发出。为何谷歌Mock会那样工作?好的,事先指按期望允许GoogleMock在上下文(客栈追踪等卡塔 尔(英语:State of Qatar)依旧可用时及时告诉违例。这使得调节和测量试验更易于。

的确,这一个测量试验是布置的,未有做太多。您能够轻易完成均等的功用,而没有必要接收GoogleMock。但是,正如大家将便捷发表的,谷歌(Google卡塔 尔(阿拉伯语:قطر‎宪章允许你做越多的mock。

1.使用Google Mock与别的测验框架

如若您要利用除谷歌测验(比方CppUnit或CxxTest卡塔尔之外的其他测验框架充当测量检验框架,只需将上意气风发节中的main(卡塔尔函数修正为:

1
2
3
4
5
6
7
int main(int argc, char** argv) {
  // The following line causes Google Mock to throw an exception on failure,
  // which will be interpreted by your testing framework as a test failure.
  ::testing::GTEST_FLAG(throw_on_failure) = true;
  ::testing::InitGoogleMock(&argc, argv);
  ... whatever your testing framework requires ...
}

这种艺术有四个catch:它偶然使GoogleMock从三个仿照目的的析构器中抛出极度。对于一些编写翻译器,那有的时候会引致测量检验程序崩溃。
你还是能够小心到测验战败了,但它不是一个高贵的挫折。

越来越好的施工方案是选取谷歌(Google卡塔尔国Test的风浪侦听器API来科学地向测量检验框架报告测验失利。
您供给贯彻事件侦听器接口的OnTestPartResult(卡塔 尔(阿拉伯语:قطر‎方法,但它应当是直接的。

倘使那表达是太多的劳作,我们建议你持铁杵成针运用Google测验,它与GoogleMock无缝地专业(实际上,它在才能上是谷歌 Mock的一有个别卡塔尔国。
如若您有有个别原因不恐怕运用Google测试,请报告大家。

1.施用Google Mock与别的测量试验框架

若果您要选择除Google测量检验(举个例子CppUnit或CxxTest卡塔 尔(阿拉伯语:قطر‎之外的别的测量检验框架充任测量试验框架,只需将上风姿罗曼蒂克节中的main(卡塔尔函数校正为:

int main(int argc, char** argv) {
  // The following line causes Google Mock to throw an exception on failure,
  // which will be interpreted by your testing framework as a test failure.
  ::testing::GTEST_FLAG(throw_on_failure) = true;
  ::testing::InitGoogleMock(&argc, argv);
  ... whatever your testing framework requires ...
}

这种艺术有叁个catch:它一时使GoogleMock从叁个模仿目的的析构器中抛出格外。对于某个编写翻译器,那不经常会促成测量试验程序崩溃。
你仍然是能够小心到测量试验战败了,但它不是一个高贵的退步。

更加好的解决方案是接收GoogleTest的风浪侦听器API来不易地向测验框架报告测试战败。
您需求完成事件侦听器接口的OnTestPartResult(卡塔 尔(阿拉伯语:قطر‎方法,但它应该是直接的。

要是那表明是太多的劳作,大家提出你坚定不移利用Google测量检验,它与GoogleMock无缝地职业(实际上,它在本事上是谷歌(Google卡塔尔 Mock的意气风发局地卡塔尔。
假设您有有个别原因无法使用谷歌(Google卡塔 尔(阿拉伯语:قطر‎测量检验,请报告大家。

七、设置期待

家成业就使用模拟目的的重大是对它设置科学的梦想。
要是您设置的愿意太严酷,你的测验将战败作为毫不相关的转移的结果。
倘诺你把它们设置得太松,错误能够透过。
你想做的只是科学的,让你的测量检验能够捕获到你想要捕获的这种错误。 GoogleMock为您提供了尤为重要的办法“善刀而藏”。

七、设置期望

功成业就接收模拟目的的爱抚是对它设置科学的期待。
纵然您设置的指望太严酷,你的测验将退步作为毫无干系的改过的结果。
假诺您把它们设置得太松,错误能够通过。
你想做的只是科学的,使您的测量检验能够捕获到你想要捕获的这种错误。 GoogleMock为您提供了必备的艺术“适度可止”。

1. 通用语法

在Google Mock中,大家使用EXPECT_CALL(卡塔 尔(阿拉伯语:قطر‎宏来设置模拟方法的期待值。
日常的语法是:

1
2
3
4
EXPECT_CALL(mock_object, method(matchers))
    .Times(cardinality)
    .WillOnce(action)
    .WillRepeatedly(action);

宏有四个参数:首先是mock对象,然后是格局及其参数。
请注意,两个之间用逗号(,卡塔 尔(阿拉伯语:قطر‎分隔,并非句点(.卡塔 尔(英语:State of Qatar)。
(为何要使用逗号?答案是,那是必须的手艺原因。卡塔尔

宏之后方不过部分可选的子句,提供关于期待的越来越多信息。
我们将要底下的章节中研究每种子句是如何行事的。

此语法意在使梦想读取如法文。 举例,你或许猜到

1
2
3
4
5
6
using ::testing::Return;...
EXPECT_CALL(turtle, GetX())
    .Times(5)
    .WillOnce(Return(100))
    .WillOnce(Return(150))
    .WillRepeatedly(Return(200));

 turtle对象的GetX(卡塔 尔(阿拉伯语:قطر‎方法将被调用伍次,它将第叁遍回到100,第贰次回到150,然后每一遍回来200。 有些人心爱将这种语法风格称为域特定语言(DSL卡塔尔国。

注意:干什么大家应用宏来做到这点? 它有四个目标:第风流浪漫,它使预期轻巧辨认(通过grep或由人类读者卡塔尔国,其次它同意GoogleMock在新闻中回顾失利的只求的源文件地点,使调节和测验更易于。

1. 通用语法

在Google Mock中,大家使用EXPECT_CALL(卡塔 尔(英语:State of Qatar)宏来设置模拟方法的期待值。
日常的语法是:

EXPECT_CALL(mock_object, method(matchers))
    .Times(cardinality)
    .WillOnce(action)
    .WillRepeatedly(action);

宏有五个参数:首先是mock对象,然后是方法及其参数。
请注意,两者之间用逗号(,卡塔 尔(英语:State of Qatar)分隔,并非句点(.卡塔尔国。
(为啥要动用逗号?答案是,那是必不可少的能力原因。卡塔尔国

宏之后方可是局地可选的子句,提供关于期望的愈来愈多音讯。
我们就要底下的章节中商量各个子句是何等职业的。

此语法目的在于使梦想读取如藏语。 举个例子,你恐怕猜到

using ::testing::Return;...
EXPECT_CALL(turtle, GetX())
    .Times(5)
    .WillOnce(Return(100))
    .WillOnce(Return(150))
    .WillRepeatedly(Return(200));

 turtle对象的GetX(卡塔尔方法将被调用四遍,它将首先次回到100,第二回回到150,然后每一遍回去200。 某一个人爱不忍释将这种语法风格称为域特定语言(DSL卡塔尔国。

注意:缘何大家采用宏来做到那或多或少? 它有五个目标:第生机勃勃,它使预期轻便辨认(通过grep或由人类读者卡塔尔,其次它同意GoogleMock在新闻中满含败北的盼望的源文件地方,使调节和测量试验更便于。

2.Matchers:大家盼望什么参数?

当叁个mock函数接纳参数时,大家亟须钦赐大家希望什么参数; 举例:

// Expects the turtle to move forward by 100 units.
EXPECT_CALL(turtle, Forward(100));

 

偶然候你大概不想太现实(记住,商量测量试验太固执,当先正式引致虚亏的测量检验和模糊测验的思考,由此,大家慰勉你只钦定供给的

  • 卡塔尔。 如果你想检查Forward(卡塔尔国将被调用,但对它的实在参数不感兴趣,写 _
    作为参数,那象征“任李有贞西”:
1
2
3
4
using ::testing::_;
...
// Expects the turtle to move forward.
EXPECT_CALL(turtle, Forward(_));

_ 是我们誉为匹配器的实例。
相配器就好像三个谓词,能够测量检验一个参数是还是不是是我们愿意的。
你能够在EXPECT_CALL(卡塔尔国里面使用一个相称器,只要有两个函数参数。

嵌入匹配器的列表能够在CheatSheet中找到。
举例,这里是Ge(大于或等于卡塔 尔(英语:State of Qatar)相配器:

1 using ::testing::Ge;...
2 EXPECT_CALL(turtle, Forward(Ge(100))); 

那检查,turtle将被报告前行最少100单位。

2.Matchers:我们期待什么参数?

当二个mock函数选取参数时,我们必须钦点大家希望什么参数; 比如:

// Expects the turtle to move forward by 100 units.
EXPECT_CALL(turtle, Forward(100));

  一时你大概不想太现实(记住,商议测量检验太固执,超标招致虚亏的测验和混淆测量检验的图谋,因而,大家激励你只内定需求的

  • 卡塔尔国。 假诺您想检查Forward(卡塔 尔(英语:State of Qatar)将被调用,但对它的其实参数不感兴趣,写 _
    作为参数,那象征“任何事物”:

    using ::testing::_;

    // Expects the turtle to move forward.
    EXPECTCALL(turtle, Forward());

_ 是我们誉为相配器的实例。
相称器就如三个谓词,可以测量检验一个参数是或不是是我们期望的。
你可以在EXPECT_CALL(卡塔 尔(英语:State of Qatar)里面使用一个相配器,只要有一个函数参数。

内置相配器的列表能够在CheatSheet中找到。
比如,这里是Ge(大于或等于卡塔 尔(英语:State of Qatar)相配器:

1 using ::testing::Ge;...
2 EXPECT_CALL(turtle, Forward(Ge(100))); 

那检查,turtle将被报告前行至少100单位。

3. cardinality:它会被调用多少次?

咱俩得以在EXPECT_CALL(卡塔 尔(阿拉伯语:قطر‎之后内定的率先个子句是Times(卡塔 尔(英语:State of Qatar)。大家把它的参数称为基数,因为它告诉调用应该产生多少次。它同意我们再一次二个梦想多次,而不实际写数次。更重视的是,一个基数能够是“模糊的”,就好像多个相称器。那允许客户准确地球表面述测验的盘算。

一个神乎其神的例外意况是当大家说Times(0卡塔 尔(阿拉伯语:قطر‎。你恐怕早已猜到了 –
那代表函数不该选拔给定的参数,何况GoogleMock会在函数被(错误地卡塔尔国调用时告知一个Google测验战败。

我们曾经观看AtLeast(n卡塔尔国作为模糊基数的一个例子。有关您能够采纳的放置基数列表,请参见CheatSheet。

Times(卡塔尔子句能够归纳。倘让你省略Times(卡塔尔国,GoogleMock会猜测出您的基数。法规超轻巧记住:

  • 如果WillOnce()和WillRepeatedly()都不在EXPECT_CALL(卡塔 尔(阿拉伯语:قطر‎中,则臆想的基数是Times(1卡塔 尔(英语:State of Qatar)。
  • 如果有n个WillOnce(),但没有WillRepeatedly(),其中n> =
    1,基数是Times(n)
  • 如果有n个WillOnce()和一个WillRepeatedly(),其中n> =
    0,基数是Times(AtLeast(n))。

迅快速检验验:假使二个函数被调用五次,但实则调用了九次,你感到会发出哪些?

3. cardinality:它会被调用多少次?

咱俩得以在EXPECT_CALL(卡塔尔之后内定的率先个子句是Times(卡塔尔。我们把它的参数称为基数,因为它告诉调用应该发生多少次。它同意大家再一次贰个可望数次,而不实际写数拾回。更首要的是,八个基数能够是“模糊的”,就疑似三个匹配器。那允许客商正确地球表面述测验的妄图。

七个有趣的特殊景况是当大家说Times(0卡塔尔。你也许早就猜到了 –
那象征函数不该采用给定的参数,并且GoogleMock会在函数被(错误地卡塔尔调用时报告二个Google测量检验失败。

大家曾经看见AtLeast(n卡塔 尔(英语:State of Qatar)作为模糊基数的三个例证。有关您可以选取的嵌入基数列表,请参见CheatSheet。

Times(卡塔 尔(阿拉伯语:قطر‎子句能够轻易。假如你省略Times(卡塔尔国,GoogleMock会猜度出您的基数。法则比较轻便记住:

  • 如果WillOnce()和WillRepeatedly()都不在EXPECT_CALL(卡塔 尔(英语:State of Qatar)中,则猜想的基数是Times(1卡塔尔国。
  • 如果有n个WillOnce(),但没有WillRepeatedly(),其中n> =
    1,基数是Times(n)
  • 如果有n个WillOnce()和一个WillRepeatedly(),其中n> =
    0,基数是Times(AtLeast(n))。

快速检查测试:就算叁个函数被调用一次,但实在调用了陆次,你感觉会发生什么样?

4.Action:应该如何是好?

铭记,贰个效仿目的实际失业完毕?
咱们作为顾客必须告诉它当几个方法被调用时该做怎么着。 那在GoogleMock中相当的轻松。

先是,假如贰个仿照函数的回到类型是放到类型或指针,该函数有叁个暗中同意动作(三个void函数将回来,一个bool函数将赶回false,别的函数将重返0卡塔 尔(阿拉伯语:قطر‎。别的,在C
++
11及以上版本中,再次回到类型为默承认组织(即全部默许构造函数卡塔尔国的效仿函数具备重回私下认可构造值的默许动作。
倘令你不说哪些,那个行为将被采取。

第二,假若模拟函数未有暗中同意动作,只怕暗中认可动作不合乎你,你可以利用大器晚成种类WillOnce(卡塔尔子句内定每便期待相称时要使用的动作,后跟二个可选的WillRepeatedly
(卡塔尔国。例如,

1
2
3
4
5
using ::testing::Return;...
EXPECT_CALL(turtle, GetX())
    .WillOnce(Return(100))
    .WillOnce(Return(200))
    .WillOnce(Return(300));

这注解turtle.GetX(卡塔尔国将被调用一遍(谷歌(Google卡塔尔Mock从大家写的威尔Once(卡塔 尔(阿拉伯语:قطر‎子句中猜度出了那点,因为大家从不鲜明写入Times(卡塔尔国卡塔 尔(阿拉伯语:قطر‎,並且会回去100,200,
和300。

1
2
3
4
5
using ::testing::Return;...
EXPECT_CALL(turtle, GetY())
    .WillOnce(Return(100))
    .WillOnce(Return(200))
    .WillRepeatedly(Return(300));

 turtle.GetY(卡塔尔国将被调用起码一遍(GoogleMock知道那或多或少,因为大家写了三个WillOnce(卡塔尔国子句和叁个WillRepeatedly(卡塔尔国,未有明了的提姆es(卡塔尔卡塔尔国,将率先次回到100,200
第壹回,300从第三遍开首。

自然,假若你确定写二个Times(卡塔尔国,谷歌(Google卡塔 尔(英语:State of Qatar)Mock不会酌量推测cardinality(基数卡塔尔国本人。
假诺你钦赐的数字超越威尔Once(卡塔 尔(英语:State of Qatar)子句,该如何做?
好了,毕竟WillOnce(卡塔 尔(阿拉伯语:قطر‎已用完,谷歌Mock每趟都会为函数实践默许操作(除非您有威尔Repeatedly(卡塔 尔(阿拉伯语:قطر‎。卡塔 尔(阿拉伯语:قطر‎。

除此而外Return(卡塔 尔(英语:State of Qatar)之外,大家能够在威尔Once(卡塔尔国中做怎么样?
您能够行使ReturnRef(variable卡塔尔重返引用,或调用预订义函数等。

关键表明:EXPECT_CALL()语句只评估一遍操作子句,即便操作大概实践多次。
由此,您必得小心副成效。 以下可能不会做你想要的:

1
2
3
4
int n = 100;
EXPECT_CALL(turtle, GetX())
.Times(4)
.WillRepeatedly(Return(n++));

不是三番五次重回100,101,102,…,这些mock函数将连接回到100,因为n
++只被总计二遍
。 类似地,当执行EXPECT_CALL(卡塔 尔(阿拉伯语:قطر‎时,Return(new
Foo卡塔 尔(英语:State of Qatar)将创建两个新的Foo对象,何况每一回都回来相符的指针。
假若你想要每一回都发生副作用,你必要定义一个自定义动作,我们将要 CookBook中教授。

日子另一个考试! 你感觉以下是如何看头?

1
2
3
4
using ::testing::Return;...
EXPECT_CALL(turtle, GetY())
.Times(4)
.WillOnce(Return(100));

鲜明turtle.GetY()被冀望调用七回。但万大器晚成您感觉它会每一回回去100,深思熟虑!请记住,每趟调用函数时都将接受三个WillOnce(卡塔尔子句,然后试行暗中认可操作。所以精确的答案是turtle.GetY(卡塔尔国将率先次回到100,但从第叁回再次回到0,因为重回0是int函数的暗中认可操作

4.Action:应该如何做?

纪事,二个效仿指标实际并未有专门的学问完成?
我们作为客商必需告诉它当八个办法被调用时该做什么样。 那在GoogleMock中相当的轻便。

第大器晚成,倘若多个模拟函数的归来类型是放到类型或指针,该函数有叁个暗中认可动作(三个void函数将重回,二个bool函数将回来false,别的函数将再次回到0卡塔尔国。其它,在C
++
11及以上版本中,重临类型为默许同协会(即怀有暗中同意构造函数卡塔尔国的模仿函数具备重临暗中同意构造值的默许动作。
假若您不说如何,这么些作为将被选用。

其次,借使模拟函数未有默许动作,或许默许动作不合乎您,你能够行使意气风发层层WillOnce(卡塔尔国子句钦赐每一遍期待匹配时要使用的动作,后跟一个可选的WillRepeatedly
(卡塔尔。例如,

using ::testing::Return;...
EXPECT_CALL(turtle, GetX())
    .WillOnce(Return(100))
    .WillOnce(Return(200))
    .WillOnce(Return(300));

那表明turtle.GetX(卡塔 尔(阿拉伯语:قطر‎将被调用叁遍(GoogleMock从我们写的威尔Once(卡塔尔国子句中揣摸出了这或多或少,因为我们并未有明了写入Times(卡塔 尔(英语:State of Qatar)卡塔 尔(英语:State of Qatar),而且会重返100,200,
和300。

using ::testing::Return;...
EXPECT_CALL(turtle, GetY())
    .WillOnce(Return(100))
    .WillOnce(Return(200))
    .WillRepeatedly(Return(300));

 turtle.GetY(卡塔 尔(英语:State of Qatar)将被调用最少两回(谷歌(Google卡塔尔Mock知道这或多或少,因为大家写了多个WillOnce(卡塔 尔(阿拉伯语:قطر‎子句和叁个WillRepeatedly(卡塔尔,未有分明性的Times(卡塔 尔(阿拉伯语:قطر‎卡塔尔国,将率先次回到100,200
第二遍,300从第三次开端。

当然,假让你分明写二个Times(卡塔尔,GoogleMock不会酌量揣测cardinality(基数卡塔 尔(英语:State of Qatar)自己。
倘让你钦点的数字高于WillOnce(卡塔 尔(英语:State of Qatar)子句,该咋办?
好了,究竟WillOnce(卡塔尔国已用完,GoogleMock每趟都会为函数施行暗许操作(除非你有WillRepeatedly(卡塔尔国。卡塔尔。

除此之外Return(卡塔 尔(英语:State of Qatar)之外,我们能够在威尔Once(卡塔 尔(英语:State of Qatar)中做什么样?
您能够接收ReturnRef(variable卡塔尔重临援引,或调用预订义函数等。

重视表明:EXPECT_CALL()语句只评估三次操作子句,纵然操作或许进行数次。
由此,您必得小心副作用。 以下大概不会做你想要的:

int n = 100;
EXPECT_CALL(turtle, GetX())
.Times(4)
.WillRepeatedly(Return(n++));

不是接二连三再次回到100,101,102,…,那些mock函数将接二连三回到100,因为n
++只被计算二回
。 类似地,当执行EXPECT_CALL(卡塔 尔(阿拉伯语:قطر‎时,Return(new
Foo卡塔尔国将开创三个新的Foo对象,并且每一回都回去相通的指针。
借让你想要每回都发出副功用,你必要定义二个自定义动作,大家将要 库克Book中等教育授。

时光另一个试验! 你认为以下是什么样看头?

using ::testing::Return;...
EXPECT_CALL(turtle, GetY())
.Times(4)
.WillOnce(Return(100));

鲜明turtle.GetY(卡塔 尔(阿拉伯语:قطر‎被期望调用七次。但假诺你以为它会每一趟回到100,冥思苦索!请深深记住,每便调用函数时都将利用贰个WillOnce(卡塔尔子句,然后实行私下认可操作。所以正确的答案是turtle.GetY(卡塔尔将第一遍回到100,但从第三回重临0,因为重返0是int函数的暗中同意操作

5.运用多个梦想

到最近甘休,大家只列出了你有一个希望的例子。更现实地,你要钦定对多个模拟方法的期望,那可能来自八个模拟指标。

暗中认可处境下,当调用模拟方法时,GoogleMock将根据它们定义的反而顺序找寻期待值,并在找到与参数相配的活动希望时停下(您能够将其正是“新准绳覆盖旧的平整“卡塔 尔(英语:State of Qatar)。假诺相配期待不可能再承当任何调用,您将收获叁个上限违反的挫败。这里有叁个事例:

1
2
3
4
using ::testing::_;...
EXPECT_CALL(turtle, Forward(_));  // #1
EXPECT_CALL(turtle, Forward(10))  // #2
    .Times(2);

如果Forward(10卡塔尔国留意气风发行中被调用一回,首次它将是八个不当,因为最后的合作期待(#2卡塔 尔(阿拉伯语:قطر‎已经饱和。但是,借使第两个Forward(10卡塔 尔(阿拉伯语:قطر‎被Forward(20卡塔尔国替换,则它将是OK,因为前日#1将是配合期望。

附注:GoogleMock为啥要以与预期相反的逐意气风发搜寻相配?原因是,那允许客户在模拟指标的构造函数中设置暗中同意期待,或测量试验夹具的设置阶段中安装私下认可期待,然后经过在测量试验体中写入更绘声绘色的愿意来定制模拟。所以,假设您对同多少个方法有两个希望,你想把一个具备越来越多的一定的相配器放在另叁个过后,或更现实的规行矩步将被进一层相近的中规中矩所覆盖。

5.施用多少个梦想

到近日截止,大家只列出了你有二个希望的事例。更现实地,你要钦点对多少个模拟方法的盼望,那或然出自两个模拟目的。

暗中同意情状下,当调用模拟方法时,GoogleMock将如约它们定义的反而顺序追寻期望值,并在找到与参数匹配的运动希望时停下(您能够将其正是“新准则覆盖旧的平整“卡塔 尔(英语:State of Qatar)。假若同盟期待不能够再负责负何调用,您将获得八个上限违反的失败。这里有叁个例子:

using ::testing::_;...
EXPECT_CALL(turtle, Forward(_));  // #1
EXPECT_CALL(turtle, Forward(10))  // #2
    .Times(2);

如果Forward(10卡塔 尔(英语:State of Qatar)在生机勃勃行中被调用壹次,第二次它将是一个荒诞,因为最后的异常期待(#2卡塔尔国已经饱和。可是,若是第八个Forward(10卡塔 尔(阿拉伯语:قطر‎被Forward(20卡塔 尔(英语:State of Qatar)替换,则它将是OK,因为明天#1将是异常期待。

附注:GoogleMock为何要以与预期相反的逐个搜寻相称?原因是,那允许客户在模拟指标的构造函数中安装暗中同意期待,或测量检验夹具的装置阶段中装置私下认可期待,然后经过在测验体中写入更具象的愿意来定制模拟。所以,倘若你对同叁个方法有八个期望,你想把二个有所越多的特定的相称器放在另三个过后,或更具体的准则将被越来越形似的平整所隐讳。

6.有序和九冬呼叫

私下认可景况下,即便未满意较早的冀望,期待也得以协作调用。换句话说,调用不必根据期待被钦命的依次爆发

一时,您或者希望全部预期的调用以从严的生龙活虎一产生。在谷歌(Google卡塔尔Mock中说那十分轻便:

1
2
3
4
5
6
7
8
9
10
11
12
using ::testing::InSequence;...
TEST(FooTest, DrawsLineSegment) {
  ...
  {
    InSequence dummy;
 
    EXPECT_CALL(turtle, PenDown());
    EXPECT_CALL(turtle, Forward(100));
    EXPECT_CALL(turtle, PenUp());
  }
  Foo();
}

透过创建项目为InSequence的对象,其范围中的全部相当的大可能率都被放入体系中,何况必需按顺序产生。因为大家只是依据这么些指标的构造函数和析构函数做实在的工作,它的名字真个不值风度翩翩提。

在此个例子中,大家测量检验Foo(卡塔尔国根据书写的顺序调用多个希望函数。借使调用是冬天的,它将是一个不当。

(假设您关怀一些呼叫的相对顺序,但不是享有的呼唤,你能钦命一个私下的片段每个吗?答案是…是的!假如您不耐性,细节能够在库克Book中找到。卡塔尔

6.有序和冬天呼叫

暗中同意意况下,尽管未知足较早的期望,期待也得以合作调用。换句话说,调用不必依据期待被钦点的依次发生

临时候,您也许希望全数预期的调用以严谨的逐条爆发。在GoogleMock中说那非常轻便:

using ::testing::InSequence;...
TEST(FooTest, DrawsLineSegment) {
  ...
  {
    InSequence dummy;

    EXPECT_CALL(turtle, PenDown());
    EXPECT_CALL(turtle, Forward(100));
    EXPECT_CALL(turtle, PenUp());
  }
  Foo();
}

经过创造项目为InSequence的对象,其范围中的全部非常大希望都被归入连串中,何况必需按梯次产生。因为大家只是依靠那个指标的构造函数和析构函数压实际的办事,它的名字真个不值风流倜傥提。

在这里个事例中,我们测量检验Foo(卡塔尔依据书写的顺序调用八个希望函数。假如调用是严节的,它将是五个荒诞。

(倘让你保护一些呼唤的周旋顺序,但不是怀有的呼叫,你能内定三个即兴的有的每个吧?答案是…是的!假如您不耐心,细节能够在库克Book中找到。卡塔尔

7. 兼有望都以粘滞的(Sticky)(除非另有认证卡塔尔

今昔,让大家做三个迅快速检检查实验,看看您能够多好地动用那么些宪章的事物。你会如何测量检验,turtle被要求去原点两回(你想忽略任何别的指令卡塔 尔(阿拉伯语:قطر‎?

在你提议了你的答案,看看大家的可比的笔记(本身先解决 – 不要欺诈!卡塔尔国:

1
2
3
4
5
using ::testing::_;...
EXPECT_CALL(turtle, GoTo(_, _))  // #1
    .Times(AnyNumber());
EXPECT_CALL(turtle, GoTo(0, 0))  // #2
    .Times(2);

假设turtle.GoTo(0,0卡塔 尔(阿拉伯语:قطر‎被调用了三次。 第二次,谷歌Mock将见到参数相称期待#2(记住,大家总是挑肥拣瘦最终叁个相当期待卡塔尔国。
今后,由于我们说应该唯有多个那样的调用,谷歌 Mock会立刻告诉错误。
那基本上是大家在地方“使用四个梦想”部分中报告你的。

其一事例表明,GoogleMock的期望在暗中同意意况下是“粘性”,就算在咱们落成其调用上界之后,它们还是保持活动。
那是三个尤为重要的平整要切记,因为它影响标准的含义,何况分歧于它在不菲其余Mock框架中做的(为何我们那样做?因为大家感到大家的平整使周边的情事更便于表明和
精晓。卡塔尔。

简言之? 让大家看看你是还是不是真正通晓它:下边的代码说怎样?

1
2
3
4
5
6
using ::testing::Return;
...
for (int i = n; i > 0; i--) {
  EXPECT_CALL(turtle, GetX())
      .WillOnce(Return(10*i));
}

生龙活虎经您以为它说,turtle.GetX(卡塔 尔(阿拉伯语:قطر‎将被调用n次,并将赶回10,20,30,…,接二连三,深思熟虑!
难点是,正如我们所说,期望是粘性的。
所以,第叁回turtle.GetX(卡塔 尔(英语:State of Qatar)被调用,最终(最新卡塔 尔(英语:State of Qatar)EXPECT_CALL(卡塔尔国语句将相配,并将立即引致“上限超过(upper
bound exceeded)”错误 – 这段代码不是很有用!

五个没有错的传教是turtle.GetX(卡塔 尔(英语:State of Qatar)将再次回到10,20,30,…,是分明说,期待是不粘的。
换句话说,他们理应在饱和后飞快退休:

1
2
3
4
5
6
7
using ::testing::Return;
...
for (int i = n; i > 0; i--) {
  EXPECT_CALL(turtle, GetX())
    .WillOnce(Return(10*i))
    .RetiresOnSaturation();
}

何况,有三个越来越好的措施:在这里种情景下,大家期望调用产生在一个一定的大器晚成生龙活虎,我们排列动作来合作顺序。
由于种种在这里边很要紧,大家应当出示的使用三个风度翩翩生机勃勃:

1
2
3
4
5
6
7
8
9
10
11
12
using ::testing::InSequence;
using ::testing::Return;
...
{
  InSequence s;
 
  for (int i = 1; i <= n; i++) {
    EXPECT_CALL(turtle, GetX())
        .WillOnce(Return(10*i))
        .RetiresOnSaturation();
  }
}

附带说一下,期待或然不粘的别的情状是当它在二个行列 —
风流罗曼蒂克旦种类中的在他自此的愿意已经使用,它自动退休(况兼长久不会用来相称任何调用卡塔 尔(阿拉伯语:قطر‎。

7. 颇有希望都以粘滞的(Sticky)(除非另有认证卡塔 尔(英语:State of Qatar)

现今,让我们做叁个飞跃检查评定,看看您可以多好地采纳这么些宪章的事物。你会怎样测验,turtle被必要去原点两遍(你想忽略任何其余指令卡塔 尔(英语:State of Qatar)?

在您提议了您的答案,看看我们的相比较的笔记(本身先消除 – 不要欺诈!卡塔尔国:

using ::testing::_;...
EXPECT_CALL(turtle, GoTo(_, _))  // #1
    .Times(AnyNumber());
EXPECT_CALL(turtle, GoTo(0, 0))  // #2
    .Times(2);

假使turtle.GoTo(0,0卡塔尔国被调用了贰遍。 第一遍,谷歌Mock将见到参数相配期望#2(记住,大家总是拈轻怕重最终贰个精雕细刻期望卡塔尔。
今后,由于大家说应该独有七个这么的调用,谷歌 Mock会立时告知错误。
这基本上是大家在地点“使用八个希望”部分中告诉您的。

本条例子申明,GoogleMock的希望在私下认可景况下是“粘性”,纵然在我们完成其调用上界之后,它们依旧保持活动。
那是多少人命关天的规行矩步要切记,因为它影响规范的意义,何况分裂于它在重重任何Mock框架中做的(为啥我们如此做?因为大家以为我们的法规使周围的图景更便于表明和
驾驭。卡塔 尔(英语:State of Qatar)。

总结? 让大家看看你是或不是确实精通它:上面包车型地铁代码说怎么?

using ::testing::Return;
...
for (int i = n; i > 0; i--) {
  EXPECT_CALL(turtle, GetX())
      .WillOnce(Return(10*i));
}

假定你感到它说,turtle.GetX(卡塔 尔(英语:State of Qatar)将被调用n次,并将回来10,20,30,…,一而再,深思远虑!
难点是,正如大家所说,期望是粘性的。
所以,第三次turtle.GetX(卡塔 尔(英语:State of Qatar)被调用,最终(最新卡塔 尔(英语:State of Qatar)EXPECT_CALL(卡塔 尔(阿拉伯语:قطر‎语句将合营,并将任何时候导致“上限超越(upper
bound exceeded)”错误 – 这段代码不是很有用!

五个不利的说法是turtle.GetX(卡塔 尔(阿拉伯语:قطر‎将赶回10,20,30,…,是赫赫有名说,期待是不粘的。
换句话说,他们应当在饱和后赶忙退休:

using ::testing::Return;
...
for (int i = n; i > 0; i--) {
  EXPECT_CALL(turtle, GetX())
    .WillOnce(Return(10*i))
    .RetiresOnSaturation();
}

相同的时候,有叁个更加好的办法:在这里种状态下,大家盼望调用发生在二个特定的逐风华正茂,我们排列动作来合作顺序。
由于各样在此很要紧,我们应当显得的行使三个逐项:

using ::testing::InSequence;
using ::testing::Return;
...
{
  InSequence s;

  for (int i = 1; i <= n; i++) {
    EXPECT_CALL(turtle, GetX())
        .WillOnce(Return(10*i))
        .RetiresOnSaturation();
  }
}

顺手说一下,期待可能不粘的其它情状是当它在二个连串 —
生机勃勃旦类别中的在她随后的指望已经接纳,它自动退休(何况永恒不会用来相配任何调用卡塔尔国。

8. 无趣呼叫

宪章目的恐怕有不胜枚举艺术,实际不是具有的都以那么风趣。比如,在一些测试中,大家可能不关注GetX(卡塔 尔(英语:State of Qatar)和GetY()被调用多少次。

在谷歌(Google卡塔尔国Mock中,纵然你对二个方法不感兴趣,只是别说怎样。倘诺调用此办法,您就要测验输出中来看三个告诫,但它不会倒闭。

8. 无趣呼叫

宪章目的恐怕有成都百货上千艺术,而不是具有的都以那么风趣。举例,在一些测验中,我们兴许不关注GetX(卡塔尔和GetY(卡塔 尔(英语:State of Qatar)被调用多少次。

在GoogleMock中,假若您对贰个方法不感兴趣,只是不要讲哪些。纵然调用此格局,您就要测量检验输出中来看三个警示,但它不会停业。

八、以后如何是好?

恭贺!您已经学会了十足的谷歌Mock开头运用它。今后,您也许想要参与googlemock切磋组,並且实际利用谷歌(Google卡塔 尔(英语:State of Qatar)Mock编写一些测验 – 那很有意思。嘿,它以至足以上瘾 – 你已经被警示。

然后,假让你想扩张你的Mock商,你应当移动到 CookBook。您可以通晓GoogleMock的重重高端作用,并提升你的分享和测验幸福的品位。

八、未来怎么办?

恭喜!您已经学会了十足的GoogleMock伊始应用它。今后,您只怕想要到场googlemock研商组,并且实际利用谷歌Mock编写一些测验 – 那很有意思。嘿,它以致能够上瘾 – 你已经应诉诫。

下一场,假诺您想扩大你的Mock商,你应当移动到 CookBook。您能够精晓谷歌Mock的重重尖端成效,并进步你的享受和测量检验幸福的程度。

九、七个小例子

那是自个儿写的一个小例子,很简单的例子:

1
2
3
4
5
6
7
8
//定义需要模拟的接口类
    class FooInterface {
    public:
        virtual ~FooInterface() {}
        virtual std::string getArbitraryString() = 0;
 
        virtual int getPosition() = 0;
    };

  

1
2
3
4
5
6
//模拟类
class MockFoo : public FooInterface {
    public:
        MOCK_METHOD0(getArbitraryString, std::string());
        MOCK_METHOD0(getPosition, int());
    };

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include "stdafx.h"
 
using namespace seamless;
using namespace std;
 
using ::testing::Return;
 
int main(int argc, char** argv) {
    //Since Google Mock depends on Google Test, InitGoogleMock() is also responsible for initializing Google Test.
    //Therefore there's no need for calling testing::InitGoogleTest() separately.
    ::testing::InitGoogleMock(&argc, argv);
    int n = 100;
    string value = "Hello World!";
    MockFoo mockFoo;
    EXPECT_CALL(mockFoo, getArbitraryString())
        .Times(1)
        .WillOnce(Return(value));
    string returnValue = mockFoo.getArbitraryString();
    cout << "Returned Value: " << returnValue << endl;
    //在这里Times(2)意思是调用两次,但是下边只调用了一次,所以会报出异常
    EXPECT_CALL(mockFoo, getPosition())
        .Times(2)     
        .WillRepeatedly(Return(n++));
    int val = mockFoo.getPosition();  //100
    cout << "Returned Value: " << val << endl;
    //getPosition指定了调用两次,这里只调用了一次,所以运行结果显示出错
    return EXIT_SUCCESS;
}

  运营结果:

威尼斯人平台 1

 能够见到上面都输出了,最终有个谬误,那么些荒唐是因为:getPosition钦赐了调用三回,这里只调用了二次,所以运转结果展现出错

 转发请评释出处:

九、一个小例子

那是本身写的多个小例子,比非常粗大略的例证:

//定义需要模拟的接口类
 class FooInterface {
 public:
  virtual ~FooInterface() {}
  virtual std::string getArbitraryString() = 0;

  virtual int getPosition() = 0;
 };

  

//模拟类
class MockFoo : public FooInterface {
 public:
  MOCK_METHOD0(getArbitraryString, std::string());
  MOCK_METHOD0(getPosition, int());
 };

  

#include "stdafx.h"

using namespace seamless;
using namespace std;

using ::testing::Return;

int main(int argc, char** argv) {
 //Since Google Mock depends on Google Test, InitGoogleMock() is also responsible for initializing Google Test.
 //Therefore there's no need for calling testing::InitGoogleTest() separately.
 ::testing::InitGoogleMock(&argc, argv);
 int n = 100;
 string value = "Hello World!";
 MockFoo mockFoo;
 EXPECT_CALL(mockFoo, getArbitraryString())
  .Times(1)
  .WillOnce(Return(value));
 string returnValue = mockFoo.getArbitraryString();
 cout << "Returned Value: " << returnValue << endl;
 //在这里Times(2)意思是调用两次,但是下边只调用了一次,所以会报出异常
 EXPECT_CALL(mockFoo, getPosition())
  .Times(2)      
  .WillRepeatedly(Return(n++));
 int val = mockFoo.getPosition();  //100
 cout << "Returned Value: " << val << endl;
 //getPosition指定了调用两次,这里只调用了一次,所以运行结果显示出错
 return EXIT_SUCCESS;
}

  运转结果:

威尼斯人平台 2

 能够见到上边都输出了,最终有个谬误,这些错误是因为:getPosition钦赐了调用三遍,这里只调用了二回,所以运营结果展现出错

 转发请表明出处:

C++单元测量检验框架GoogleTest—GoogleMock简单介绍–概念及幼功语法,javamock框架
就在后日总算做了gtest的享受,笔者的预研专门的工作终于结束了,感到…

相关文章