相关文章推荐
单身的菠萝  ·  Qt ...·  1 年前    · 
大方的烤地瓜  ·  Code First ...·  1 年前    · 

GoogleTest中的gMock是一个库,用于创建mock类并使用它们。
当你编写原型或测试(prototype or test)时,完全依赖真实对象通常是不可行或不明智的(not feasible or wise)。 模拟对象(mock object)实现了与真实对象相同的接口,但是需要你在运行时指定它将如何使用以及它应该做什么 .在测试驱动开发(TDD, Test-Driven Development)中经常使用.
当使用gMock时,首先,使用一些简单的宏来描述要mock的接口,它们将扩展到mock类的实现;接下来,你将创建一些mock对象,并使用直观的语法指定其期望和行为;然后练习(exercise)使用mock对象的code. gMock将在出现任何违反预期的行为时立即捕获(catch)它.

MOCK_METHOD宏语法如下: MOCK_METHOD宏将生成定义

MOCK_METHOD(return_type,method_name, (args...));
MOCK_METHOD(return_type,method_name, (args...), (specs...));

参数依次是:接口返回值类型、接口名、接口形参列表。可选的第四个参数specs...是以逗号分隔的限定符列表,接收限定符包括:const、override、noexcept、Calltype(calltype)、ref(qualifier). 如果参数没有适当地用圆括号括起来,那么参数中的逗号将阻止MOCK_METHOD正确地解析参数 .
MOCK_METHOD必须在mock类定义的public部分中使用 ,无论被mock的方法在基类中是public, protected, 还是private.

在gMock中, 使用EXPECT_CALL宏来设置对mock方法的期望 ,EXPECT_CALL宏语法如下:

EXPECT_CALL(mock_object,method_name(matchers...))

创建一种期望(expectation),设置mock object的预期行为:第一个参数是mock object;第二个参数是mock object中的方法,两者用逗号分隔,如果有参数需要同时把参数传进去
通过EXPECT_CALL来指定Mock Object的对应行为
EXPECT_CALL必须在执行(exercises)mock对象的任何代码之前.
参数matchers...是一个以逗号分隔的匹配器列表(list of matchers),对应于方法method_name的每个参数。期望仅适用于参数与所有匹配器匹配的method_name调用.如果省略(matchers...),则期望的行为就像每个参数的匹配器都是通配符匹配器(_)一样。
宏的任何一种形式都可以后跟一些可选子句,这些子句提供有关期望的更多信息 。以下可链接子句(chainable clauses)可用于修改期望,并且必须按以下顺序使用:

EXPECT_CALL(mock_object, method_name(matchers...))
    .With(multi_argument_matcher)  // Can be used at most once
    .Times(cardinality)            // Can be used at most once
    .InSequence(sequences...)      // Can be used any number of times
    .After(expectations...)        // Can be used any number of times
    .WillOnce(action)              // Can be used any number of times
    .WillRepeatedly(action)        // Can be used at most once
    .RetiresOnSaturation();        // Can be used at most once

(1).With:将期望限制为仅应用于其参数整体与多参数匹配器multi_argument_matcher匹配的mock函数调用.With子句最多可以在期望中使用一次,并且必须是第一个子句;
(2).Times:指定期望mock函数调用的次数.参数cardinality(基数)表示期望调用的数量,可以是以下之一,都定义在::testing命名空间中:AnyNumber()、AtLeast(n)、AtMost(n)、Between(m, n)、Exactly(n) or n;
(3).InSequence:指定mock函数调用应按特定顺序进行.参数sequences...是任意数量的序列对象.
(4).After:指定mock函数调用顺序发生在一个或多个其它调用之后.
(5).WillOnce:为单个匹配函数调用指定mock函数在被调用时的实际行为.参数action表示函数调用将执行的操作.
(6).WillRepeatedly:为所有后续匹配函数调用指定mock函数在调用时的实际行为。在执行WillOnce子句中指定的操作(如果有)后生效。
(7).RetiresOnSaturation:指示在达到期望的匹配函数调用数后,期望将不再处于活动状态.
gMock要求在调用mock函数之前设置期望值,否则行为是未定义的 。不要在调用EXPECT_CALL和调用mock函数之间交替,并且在将mock传递给API后,不要对mock设置任何期望。这意味着EXPECT_CALL应该被解读为预期将来会发生调用,而不是调用已经发生。
如果你对参数的值不感兴趣,将_写为参数,这意味着"任何事情都会发生".如果你不关心任何参数,而不是为每个参数指定_,你可以省略参数列表,这适用于所有非重载方法.如果方法重载,则需要通过指定参数的数量以及可能的参数类型来帮助gMock解决预期的重载问题。

ON_CALL宏语法如下:若要自定义特定mock对象的特定方法的默认操作,使用ON_CALL.它具有与EXPECT_CALL类似的语法,但它用于在不需要调用mock方法时设置默认行为

ON_CALL(mock_object,method_name(matchers...))

gMock典型的工作流程是
(1).从testing命名空间导入gMock名称,以便可以不限定地使用它们(每个文件只需执行一次);
(2).创建一些mock对象;
(3).指定你对它们的期望(一个方法将被调用多少次?用什么论证?它用过怎么做?等);
(4).练习(exercise)一些使用mock的code;如有必要,使用GoogleTest断言检查结果;如果一个mock方法被调用的次数超过预期,或者使用了错误的参数,你将立即收到错误;
(5).当mock被销毁时,gMock将自动检查是否满足了对它的所有期望.

注:以上内容主要来自于GoogleTest官方文档: gMock for Dummies | GoogleTest

以下为测试代码:

#include <string>
#include "gmock/gmock.h"
namespace gmock_ {
class Foo {
public:
	// Must be virtual as we'll inherit from Foo.
	virtual ~Foo() {}
	virtual bool SetName(const std::string& name) = 0;
	virtual std::string GetName() const = 0;
class MockFoo : public Foo {
public:
	MOCK_METHOD(bool, SetName, (const std::string&), (override));
	MOCK_METHOD(std::string, GetName, (), (const, override));
class Area {
public:
	virtual ~Area() {}
	virtual int area() = 0;
int GetValue(Area* p) { return p->area() / 2; }
class MockArea : public Area {
public:
	MOCK_METHOD(int, area, (), (override));
} // namespace gmock_
TEST(gmock, name) {
	using namespace gmock_;
	using ::testing::AtLeast;
	using ::testing::Return;
	MockFoo foo;
	EXPECT_CALL(foo, SetName("Mike"))
		.Times(AtLeast(2))
		.WillOnce(Return(1))
		.WillOnce(Return(0));
	EXPECT_TRUE(foo.SetName("Mike"));
	EXPECT_FALSE(foo.SetName("Mike"));
	EXPECT_CALL(foo, GetName())
		.Times(AtLeast(1))
		.WillRepeatedly(Return("Mike"));
	EXPECT_EQ("Mike", foo.GetName());
TEST(gmock, area) {
	using namespace gmock_;
	using ::testing::Return;
	MockArea m;
	EXPECT_CALL(m, area()).WillRepeatedly(Return(10));
	EXPECT_EQ(5, GetValue(&m));

      执行结果如下所示:

      GitHub: https://github.com/fengbingchun/Messy_Test

目录一、简单Demo二、断言2.1 ASSERT和EXPECT2.2 流三、测试TEST()四、调用测试和main() 上文(C++开发测试工具gmock的安装与使用超详解)介绍了gmock的安装、配置与基本使用案例,本文将详细介绍一下gmock的基本语法,结合上文一起食用效果更佳哦~ 一、简单Demo 首先来编写一个简单Demo,编写代码之前,首先需要将解决方案的平台与目标程序一致,这里选择的是x64,然后版本也要与目标程序一致,这里选择的是release版本。 新建一个头文件,命名为demo.h,声明
目录一、Mock深入理解二、进阶Demo2.1 共同约定2.2 小A任务2.3 我的任务 上一篇文章(C++开发测试工具gmock使用详解——对抽象接口类进行gmock打桩并测试)主要介绍了对抽象接口类进行gmock打桩的基本流程并利用简单Demo进行测试。本文将介绍gmock打桩的进阶案例,结合上文一起食用效果更佳哦~ 一、Mock深入理解 当开发者在单元测试、模块接口测试时,当这个模块需要依赖另外一个/几个类,而这时这些个类还没有开发好(因为某些原因),这时我们就可以定义了Mock对象来模拟那些没开发好
目录一、gmock介绍二、gmock下载三、gmock配置3.1 打开解决方案3.2 进行相应设置3.3 目标程序的配置四、测试 Demo五、常见问题 一、gmock介绍 gmock是google公司推出的一款开源的白盒测试工具。gmock是个很强大的东西,测试一个模块的时候,可能涉及到和其他模块交互,可以将模块之间的接口mock起来,模拟交互过程。其作用就类似白盒测试的打桩的概念。 二、gmock下载 gmock官网:https://github.com/google/googletest。 截止到20
google mock是用来配合googletest对C++项目做单元测试的。它依赖于googletest(参见我上篇文章《如何用googletest写单元测试》:),下面我来说说linux上怎么用它来做单元测试。本文包括:1、如何获取、编译googlemock;2、如何使用gmock(下面用gmock来代称google mock)配合gtest做单元测试。gmock的当前版本与gtest一样,是1.6.0。可以从这个网址获取:下载到压缩包解压后,下面我们开始编译出静态库文件