C++开发测试工具gmock使用详解(进阶)——对抽象接口类进行gmock打桩并测试

本文介绍了如何使用gmock进行单元测试的进阶应用,通过创建Mock类模拟未完成的Turtle接口实现,进行Painter类的功能测试。详细讲解了MockTurtle类的编写,以及在测试中设置期望和验证调用的方法,帮助理解gmock在实际项目中的应用。
摘要由CSDN通过智能技术生成

上一篇文章(C++开发测试工具gmock使用详解——对抽象接口类进行gmock打桩并测试)主要介绍了对抽象接口类进行gmock打桩的基本流程并利用简单Demo进行测试。本文将介绍gmock打桩的进阶案例,结合上文一起食用效果更佳哦~

一、Mock深入理解

当开发者在单元测试、模块接口测试时,当这个模块需要依赖另外一个/几个类,而这时这些个类还没有开发好(因为某些原因),这时我们就可以定义了Mock对象来模拟那些没开发好类的行为。
Mock框架可以帮助比较方便、轻松地实现这些假的依赖类。

接下来介绍一下gmock的进阶代码,加深大家对于gmock打桩的了解。

二、进阶Demo

进阶代码实现海龟turtle运动的一个程序。

2.1 共同约定

与其让我编写的应用程序直接与系统 API 通信,不如将 API 包装在一个接口中(interface),然后编写代码实现该接口:

//接口
class Turtle {
public:
	//控制turtle运动是否留下痕迹
	virtual void PenUp() = 0;	//画笔抬起
	virtual void PenDown() = 0;	//画笔落下
	//控制turtle运动方向
	virtual void Forward(int distance) = 0;	//前进
	virtual void Turn(int degrees) = 0;		//转向
	virtual void GoTo(int x, int y) = 0;	//前往(x,y)位置
	//获取turtle当前位置
	virtual int GetX() = 0;	//获取x的坐标
	virtual int GetY() = 0;	//获取y的坐标

public:
	virtual ~Turtle() {}	//析构函数必须是virtual
};

在该接口中,使用PenUp()、PenDown()来控制turtle的画笔抬起与落下,使用Forward()、Turn()和GoTo()控制其运动,最后,使用GetX()和GetY()获取当前位置。

【注意】:析构函数必须是虚拟的virtual,因为打算从中继承所有类,否则当你通过基指针删除对象时,将不会调用派生类的析构函数,而且会获得损坏的程序状态,例如内存泄露。

2.2 小A任务

正常情况下,小A同学应该编写代码实现上述接口中的7个函数,但是由于种种原因(可能是小A同学比较懒或者是被隔离了没带电脑)导致部分代码没有编写完成,因此这时就需要Mock发挥作用。
小A同学编写的代码如下:

/*

...


*/

(实际上什么也没写)

2.3 我的任务

我的任务是根据小A同学编写完成的代码进行实现更高阶的相关功能。比如利用小A同学的上述相关接口检查是否可以绘制圆形(三点绘制一个圆),以及计算当前点x+y的数值,代码如下:

class Painter
{
	Turtle* turtle;
public:
	Painter(Turtle* turtle)
		: turtle(turtle) {}

	bool DrawCircle(int, int, int) {
		turtle->PenDown();
		return true;
	}

	int DrawXandY() {
		int x = turtle->GetX();
		int y = turtle->GetY();
		return x + y;
	}

};

2.4 编写Mock类

正常情况下,我的程序通常会使用小A同学编写完成的代码进行实现。但是在测试中,可以使用Mock进行代替。这样就可以轻松检查程序正在调用的程序、参数、顺序等。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_METHOD0(GetX,int());
	MOCK_METHOD0(GetY,int());
};

实现步骤:

  • 从Turtle类中派生出一个类MockTurtle;
  • 在子类的部分中,写public : MOCK_METHOD();
  • 接下来获取函数签名,将其剪切并粘贴到宏中,并添加一个逗号 ,在函数名称和返回类型之间;
  • 如果要Mock const 方法,请添加包含的第 4 个参数(括号是必需的)。(const)
  • 重复此步骤,直到要Mock的所有private函数都已完成。(不言而喻,抽象类中的所有纯虚拟方法都必须被Mock或override

使用gmock中的一个宏(macro)MOCK_METHOD来定义Turtle中的函数。
MOCK_METHOD定义如下:
MOCK_METHOD#1(#2, #3(#4) )

  • #1:要mock的方法共有几个参数;
  • #2:要mock的方法名称;
  • #3:这个方法的返回值类型;
  • #4:这个方法的具体参数

定义Mock类时,需要决定将其放在何处,有些人将其放在cpp源文件中,当Mock界面由同一个人编写时,这可以,但是当所有者更改它时,测试可能会中断。因此建议单独放在一个h文件中。

2.5 在Test中使用Mock

在Test中使用Mock类的基本流程是:

  1. 从命名空间testing中导入gMock名称,以便可以在非限定状态下使用它们(每个文件只需执行一次)。
  2. 创建Mock对象。
  3. 指定对它们的期望(一个方法将被调用多少次?用什么参数?它应该怎么做?等)。
  4. 练习一些使用Mock的代码; (可选)使用谷歌测试断言检查结果。如果模拟方法的调用次数超出预期或参数错误,将立即收到错误。
  5. 当Mock被破坏时,gMock将自动检查是否满足了对它的所有期望。
using ::testing::AtLeast;	//#1
using ::testing::Return;

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

	Painter painter(&turtle);

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

	EXPECT_CALL(turtle, GetX())		// #3
		.WillOnce(Return(10));		//x返回10
	EXPECT_CALL(turtle, GetY())		// #3
		.WillOnce(Return(20));		//y返回20

	EXPECT_EQ(30, painter.DrawXandY());	//#4
}

EXPECT_CALL(turtle, PenDown()).Times(AtLeast(1));
表示此测试至少会检查一次调用,如果对象未调用此方法,则测试将失败。

2.6 main()

main函数中代码如下:

int main(int argc, char **argv)
{
	testing::InitGoogleTest(&argc, argv);
	return RUN_ALL_TESTS();
}

运行结果:
在这里插入图片描述

完整代码可以参考:https://download.csdn.net/download/didi_ya/83470301


ok,以上便是本文的全部内容了,如果对你有所帮助,记得点个赞哟~

参考:

  1. https://www.cnblogs.com/pugang/p/9500352.html
  2. https://www.cnblogs.com/welkinwalker/archive/2011/11/29/2267225.html
### 回答1: Can测试工具是用于测试CAN(Controller Area Network)总线通信的软件工具,主要包括Canalyser、Canoe、Canalyzer等几种。Canalyser是一款功能强大、操作简单的工具,能够捕获CAN总线上的CAN帧并进行分析,包括检测报文、过滤报文、发送报文等。Canoe是一款功能更加强大、支持多种协议的全面集成工具,可以模拟ECU(Electronic Control Unit)的功能,实现系统集成测试、仿真环境的构建等。Canalyzer可以在CAN总线上捕获、分析高速CAN2.0B、低速CAN2.0A、单线CAN等多种CAN格式数据,同时还支持LIN、FlexRay等多种总线协议的分析。 Can测试工具的C开发主要指的是使用C语言进行Can测试工具开发。C语言是一种高效、跨平台、底层良好的语言,因此在控制器领域、嵌入式系统开发中得到广泛应用。Can测试工具使用C语言开发,一方面能够提高Can测试工具的性能和执行效率,另一方面能够提供更加灵活、可扩展的功能。由于开发Can测试工具需要了解Can总线通信协议、硬件接口、数据帧格式等方面的知识,同时C语言也需要一定的编程基础,因此Can测试工具的C开发需要开发人员有较好的专业知识和技能。通过使用C语言开发Can测试工具,能够提高Can总线测试的效率、精度和可靠性,为汽车电子系统的开发测试提供重要的支持。 ### 回答2: Can测试工具是一种用于测试汽车电子控制系统的软件工具,它能够通过CAN总线与汽车ECU(电子控制单元)进行通信,获取ECU发送的数据,分析和调试数据,从而判断汽车电子控制系统是否正常工作。 Can测试工具通常是以C语言开发的,因为C语言是一种被广泛应用在嵌入式系统领域的高效编程语言,它具有代码简洁、执行效率高、可移植性好等特点,能够帮助开发者更好地开发出高效、稳定的Can测试工具。 在Can测试工具开发过程中,开发者需要熟悉相应的软件开发工具和硬件设备,例如PC机、CAN总线接口卡、多路继电器等。同时,开发者需要了解汽车电子控制系统的相关知识和技术,才能开发出功能完备、高效稳定的Can测试工具。 总的来说,Can测试工具C语言开发涉及多方面的知识和技术,需要开发者具备一定的工程实践经验和技术水平,才能顺利完成开发过程。 ### 回答3: CAN测试工具是常用于进行控制器局域网(CAN)诊断测试的软件工具。它可以用来测试和调试CAN总线时序和电气参数,诊断CAN及其节点的错误,确认CAN信号的正确连接和响应,并执行其他测试和测量。 在开发CAN测试工具时,需要掌握多种技术,包括C语言编程、CAN协议和通信接口的理解和应用,硬件电路设计以及数据处理和分析等。开发人员需要了解CAN的基本概念和结构,如CAN帧格式、ID和数据传输方式等,以及CAN常用的协议标准,例如ISO 11898和SAE J1939等。 在实际的开发工作中,可以使用许多开发工具来帮助开发人员提高效率和准确性。例如,可以使用开发板和调试器来检查代码的正确性和运行效果,使用代码编辑器和编译器来编写和调试程序,并使用CAN分析器来监控CAN总线上的通信数据。 总之,开发CAN测试工具需要深入理解CAN协议和通信技术,并掌握多种开发工具的使用,才能确保开发出高效、准确、稳定的工具软件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wendy_ya

您的鼓励将是我创作的最大动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值