Gmock如何mock系统函数

背景及其基本原理

在写UT代码过程中发现系统函数不太好打桩,网上也没搜到较好的方式。于是稍微研究了下。

在源代码中可以使用define宏来替换掉原本的系统函数,使用我们自己的mock函数,从而达到在单元测试中,随意设置自己的返回值。
下面举例将以系统函数open (const char *__path, int __oflag, ...)来进行测试
这是其中一种方法,有其他好的方法大家也可以交流

示例

需要测试的代码

//testfunc.cpp
#include<iostream>
#include<fcntl.h>
#include<unistd.h>

using namespace std;

void test_func()
{
    const char *filename="testFile";
    int fd = open(filename,O_WRONLY | O_CREAT);
    if (-1 == fd){
        cout<<"open failed"<<std::endl;
    }else if( -100 == fd ){
        cout<<"mock sucess"<<std::endl;
    }else{
        cout<<"open sucess"<<std::endl;
    }
    close(fd);
}

想要让程序输出mock sucess,就需要通过mock的方式设置返回值。

在源码中增加改动

//testfunc.cpp
#include<iostream>
#include<fcntl.h>
#include<unistd.h>

#ifdef UNIT_TEST
#include"openmock.hpp"
#define open openmock
#endif

using namespace std;

int test_func()
{
    const char *filename="testFile";
    int fd = open(filename,O_WRONLY | O_CREAT);
    if (-1 == fd){
        cout<<"open failed"<<std::endl;
    }else if( -100 == fd ){
        cout<<"mock sucess"<<std::endl;
    }else{
        cout<<"open sucess"<<std::endl;
    }
    close(fd);
    return fd;
}
#ifdef UNIT_TEST
#undef open openmock
#endif

通过宏的控制来打开或者关闭测试代码

创建mock函数的代码

//openmock.h
#pragma once

#include<gmock/gmock.h>

class MockOpen
{

public:
    MOCK_METHOD2(openmock,int(const char *__file, int __oflag));
};

extern MockOpen* g_MockOpen;

int openmock(const char *__file, int __oflag);
//openmock.cpp
#include"openmock.hpp"

int openmock(const char *file, int oflag)
{
    if (g_MockOpen == nullptr)
    {
        return -1;
    }
    return g_MockOpen->openmock(file,oflag);
}

编写ut代码

//unittest.cpp
#include<gtest/gtest.h>
#include"openmock.hpp"
#include"testopen.hpp"
MockOpen* g_MockOpen= nullptr;
using namespace ::testing;
class OpenTest : public testing::Test
{
public:
    void SetUp()
    {
        g_MockOpen = new MockOpen();
    }
    void TearDown()
    {
        delete g_MockOpen;
        g_MockOpen = nullptr;
    }
};

TEST_F(OpenTest,test)
{
    int val = -100;
    EXPECT_CALL(*g_MockOpen,openmock(_,_)).WillOnce(Return(val));
    auto ret = test_func();
    EXPECT_EQ(ret,val);

}

int main()
{
    testing::InitGoogleTest();
    return RUN_ALL_TESTS();
}

编译文件

g++ openmock.cpp unittest.cpp testopen.cpp -lgtest -lgmock -lpthread -DUNIT_TEST

结果输出

[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from OpenTest
[ RUN      ] OpenTest.test
mock sucess
[       OK ] OpenTest.test (0 ms)
[----------] 1 test from OpenTest (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[  PASSED  ] 1 test.

这个时候就mock成功,并且设置到了我们自己期望的返回值。

  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值