单元测试googletest gmock

一:Mock C code
对于c code,gcc 提供了编译链接选项:-Wl,-wrap
比如gcc编译时加入链接选项 -Wl,--wrap,malloc,
那么函数调用malloc的时候会调用自定义的__wrap_malloc,而原来的malloc会以__real_malloc进行调用。
所以程序需要定义一个__wrap_malloc,比如:

void* __wrap_malloc(size_t size) // 定义__wrap_malloc
{
    printf("__wrap_malloc called, size:%zd\n", size); // log输出
    return __real_malloc(size); // 通过__real_malloc调用真正的malloc
}

二:Mock C++ code (Google Mock/Gmock)
                    
1) google mock介绍,以及EXPECT_CALL vs ON_CALL
https://slidedeck.io/DonaldWhyte/gmock-presentation

2) Mock函数设置函数参数
SetArgReferee(value)
SetArgPointee(value)
"Assign value to the variable referenced by the N-th (0-based) argument" and
"Assign value to the variable pointed by the N-th (0-based) argument" respectively.

比如:
ON_CALL(mock, Sign(Eq(0), _))
  .WillByDefault(DoAll(SetArgPointee<1>("set argument1"), Return(0)));
 
3) using testing
using testing::_;
using testing::Return;
using testing::NiceMock;
using testing::SetArgPointee;
using testing::DoAll;

4) 示例
Gmock的前提是对于被Mock的函数所在的类,其基类提供的函数是虚函数,
这样Mock类可以继承该基类并提供Mock函数实现。

比如基类:
class MyInterfaceBase
{
public:

    virtual bool my_func(char* param1, int param2, bool *param3) = 0;
    virtual bool my_func_variable_param(char* param1, bool param2 = false) = 0;
}

Mock类:
class My_Mock: public MyInterfaceBase
{
    MOCK_METHOD3(my_func, bool(char* param1, int param2, bool *param3));
    MOCK_METHOD2(my_func_variable_param_impl, bool(char* param1, bool param2));
    
    bool my_func_variable_param(char* param1, bool param2 = false);
}

inline bool
My_Mock::my_func_variable_param(char* param1, bool param2)
{
    return my_func_variable_param_impl(char* param1, bool param2);
}


UT测试:
My_Mock *mock_ptr = new NiceMock();//NiceMock可以防止warning

ON_CALL(*mock_ptr, my_func(_, _, _)).WillByDefault(Return(true));

或者,如果想设置函数参数,比如将第三个参数bool *param3指向的值设置为true:
ON_CALL(*mock_ptr, my_func(_, _, _)).WillByDefault(
                    DoAll(SetArgPointee<2>(true), Return(true)));
                    
5) 可变参数
gmock需要指定参数个数,比如MOCK_METHOD2固定2个函数参数,如果有可变参数,需要变通。
比如基类函数my_func_variable_param是可变参数,那么对于Mock类My_Mock来说,需要将
my_func_variable_param函数代理给一个新的固定参数函数,比如my_func_variable_param_impl,
然后通过这个代理函数实现ON_CALL/EXPECT_CALL设置函数返回值。
比如:
ON_CALL(*mock_ptr, my_func_variable_param_impl(_, _,)).WillByDefault(Return(true));

对于被测试函数,其调用my_func_variable_param可以传1个(另外一个采用默认参数)或者2个参数。

                    
参考:                    
https://stackoverflow.com/questions/32911356/google-mock-functions-changing-value-of-parameter
https://stackoverflow.com/questions/13933475/gmock-setting-default-actions-on-call-vs-expect-call

 

你可能感兴趣的:(C/C)