玩转单元测试之gmock

引言

前文我们学习了gtest相关的使用,单靠gtest,有些场景仍然无法进行测试,因此就诞生了gmock。

gmock快速入门

在引入gtest时,gmock也同样引入了,因此只需要在编译时加上合适的编译选项即可,注意不同版本的gtest在使用上可能会有所不同,当前为v1.10版本。

1. 待测试文件

#ifndef __HELLO_H__
#define __HELLO_H__

#include <iostream>
#include <string>

class Tigger{
public:
    Tigger()
    {

    }
    virtual ~Tigger() {}
    virtual bool eat(const std::string& food)
    {
        if (food == "meat") {
            return true;
        }
        return false;
    }
};
class FeedTigger {
public:
    Tigger* _tigger;
    FeedTigger(Tigger* tigger)
    {
        _tigger = tigger;
    }
    bool feed(const std::string& food)
    {
        if (_tigger !=NULL && _tigger->eat(food)) {
            return true;
        }
        return false;
    }
};
#endif

2. 单测文件

#include "hello.h"
#include "gtest/gtest.h"
#include "gmock/gmock.h"

using namespace ::testing;

namespace {

class MockTigger : public Tigger {
public:
	MOCK_METHOD1(eat, bool(const std::string&));
};
TEST(TestTigger, CaseEat) 
{
    Tigger tigger;
    FeedTigger feed_tigger0(&tigger);
    EXPECT_FALSE(feed_tigger0.feed("grass"));

    MockTigger mock_tigger;
    FeedTigger feed_tigger1(&mock_tigger);
    ON_CALL(mock_tigger, eat(_))
    	.Times(1)
        .WillRepeatedly(::testing::Return(0));
    EXPECT_TRUE(feed_tigger1.feed("grass"));
}
}

可以看到,第一次在传入"grass"这个参数时,程序必定返回false,而第二次,我们使用了mock之后的结果,也就是说无论传入什么参数,返回的结果都会是true。

3. makefile文件

CXX = g++
CXXFLAGS = -Wall
LIBES = -lgtest -lgmock -lgtest_main -lpthread
LPATH = -L/tools/googletest/1.11.0/build/lib  # 替换成自己lib路径
HPATH = -I/tools/googletest/1.11.0/googletest/include/ # 替换成自己的
include路径
HPATH += -I/tools/googletest/1.11.0/googlemock/include/ # 替换成自己的
include路径

UTEST_OBJD = hello_unit_test

hello_unit_test:hello_unit_test.cpp
	${CXX} -o $@ $+ -I ../ ${HPATH} ${CXXFLAGS} ${LIBES} ${LPATH}

clean:
	rm -rf *_unit_test

gmock常用宏

1. MOCK_METHODx

其中x表示参数个数,如:

MOCK_METHOD0(func1, void());
MOCK_METHOD1(func2, int(int));
MOCK_METHOD2(func3, int(int, int));

第一个参数,funcx表示函数名,第二个参数为函数返回值和参数列表。若是mock一个模板类的成员函数,只需要使用MOCK_METHODx_T即可。

2. ON_CALL

ON_CALL(mock, func3(_, 1))
	.Times(4)
	.WillOnce(Return(0))
	.WillOnce(Return(1))
	.WillRepeatedly(Return(2));
  • func3中的参数:
    • ‘_’表示匹配任意参数
    • 1,表示匹配指定参数,即参数为1时,才能匹配,否则不会调用mock方法
  • Times,表示mock方法执行多少次
  • WillOnce,指定一次返回结果
  • WillRepeatedly,指定每次返回同样的结果
  • 上述指定mock结果之后,程序会在第一次调用func2方法时返回0,第二次返回1,第三次和第四次都返回2,第五次及之后返回真实结果。
  • 以上为基本用法,更多好玩的用法请参考官方文档

3. EXPECT_CALL

EXPECT_CALL宏在使用上与ON_CALL宏区别不大,可以参照其进行使用,主要区别在于EXPECT_CALL宏在指定调用次数(Times)后,如指定了调用3次,程序必须调用被mock的函数,使得mock结果生效3次,否则就会报测试失败或异常,而ON_CALL则不会。所以当确实需要mock结果生效指定次数时,那么就选择使用EXPECT_CALL。

总结

  • 本篇主要讲解了如何快速入门gmock以及基本语法。
  • gmock原理其实就是利用了多态的特性,通过继承需要被mock的类,然后重写其虚函数,在使用时,将被mock的对象替换成mock后的对象,这样在运行时就可以调用mock后的对象方法,从而达到测试预期。
  • 因此gmock本身只能mock虚函数,而对于non-virtual函数,如非虚成员函数、静态成员函数、全局函数、外部依赖库的函数等,该如何进行mock呢?我们将在下一篇章来介绍
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
gmock-1.7.0是Google Mock的一个版本。Google Mock是Google针对C++语言开发的一个mocking框架,用于帮助开发人员编写单元测试。该框架可以生成用于测试C++类的mock对象,使开发人员能够模拟对象的行为,以便更轻松地进行单元测试gmock-1.7.0包含了Google Mock的全部功能和特性。它提供了丰富的语法和工具,以便开发人员可以方便地创建和管理mock对象。通过使用gmock-1.7.0,开发人员可以模拟类的方法和行为,使测试更具可读性和易于理解。 gmock-1.7.0还提供了丰富的断言和验证功能,用于验证mock对象在测试期间的调用和行为。它可以捕获和比较方法的参数和返回值,以及记录方法的调用次数和顺序。这些功能使得开发人员能够更精确地验证代码的行为,从而更好地理解和解决潜在的问题。 除了基本的mocking功能外,gmock-1.7.0还提供了Mocking Cookbook,其中包含了一些常见的测试场景和解决方案。这些场景包括模拟私有方法、模拟全局函数、在测试中使用多个实例和对虚函数进行模拟等。通过参考Mocking Cookbook,开发人员可以更快地了解如何使用gmock-1.7.0来解决各种测试问题。 总而言之,gmock-1.7.0是Google Mock的一个重要版本,它提供了强大的mocking功能和详细的测试验证工具。通过使用gmock-1.7.0,开发人员可以更轻松地编写高质量的C++单元测试,从而提高软件质量和可维护性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值