EMOCK
宏(测试虚函数,不再需要用户添加控制反转支持)int test(int a, ...)
平台 | 成员函数 | 普通函数 | 杂项 | |||||||
库 | Linux | Win | Mac | 虚函数 | 普通 | 静态 | 全局 | 变参 | 模板 | 无需修改 |
EMOCK | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
CppUMock | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: | :x: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x:[0] |
mockcpp | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: | :x: | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: | :x:[1] |
googlemock | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x:[2] |
mockitopp | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x:[1] |
C-Mock | :white_check_mark: | :x: | :x: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :x: | :x:[1] |
CppFreeMock | :white_check_mark: | :x: | :x: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x:[1] |
库 | 跳转安全 | this指针可见[Windows] | 备注 |
EMOCK | :white_check_mark: | :white_check_mark: | 使用蹦床将远跳变为短跳 |
mockcpp | :x: | :x: | x64下直接使用14字节的远跳 |
CppFreeMock | :x: | :x: | x64下直接使用14字节的远跳 |
// 待测函数
int foobar(int x) {
return x;
}
// 测试时,像下面这样就可以mock
EMOCK(foobar)
.stubs()
.with(any()) // 约束匹配任意输入
.will(returnValue(1)); // 调用时返回1
// 调用会返回1
ASSERT_EQ(foobar(0), 1);
// 待测成员函数
class Foo
{
public:
void bar1(int);
virtual void bar2(double);
static int bar3();
};
////////////////////////////////////
// 指定调用的mock函数
void EMOCK_API mock_bar1(Foo* obj, int) {
// ...
}
void EMOCK_API mock_bar2(Foo* obj, double) {
// ...
}
// 测试时,像下面这样就可以mock
EMOCK(&Foo::bar1)
.stubs()
.will(invoke(mock_bar1)); // 指定调用自定义的函数而不是指定返回值
EMOCK(&Foo::bar2) // 虚成员函数并不特别
.stubs()
.will(invoke(mock_bar2));
EMOCK(Foo::bar3) // 静态函数类似全局函数,不需要&
.stubs()
.will(returnValue(1));
// 待测重载函数
int foobar(int x) {
return x;
}
double foobar(double x) {
return x;
}
// 重载函数,像下面这样就可以mock
EMOCK((int (*)(int))foobar)
.stubs()
.will(returnValue(1));
EMOCK(static_cast<double (*)(double)>(foobar))
.stubs()
.will(returnValue(1.0));
// 待测重载成员函数
class Foo
{
public:
void bar(int);
void bar(double);
};
// 重载的成员函数,像下面这样就可以mock
EMOCK((void (Foo::*)(int))&Foo::bar)
.expects(once()); // 只会调用一次
EMOCK(static_cast<void (Foo::*)(double)>(&Foo::bar))
.expects(never()); // 不会被调用
EMOCK("foo::bar")
.stubs()
.will(returnValue(1));
使用规范:[[__cdecl|__stdcall|__thiscall]#]|[!] [{<return_type>}] [<namespace>::] [<class>::] <function> [(<argument_list>)] [@<library>]
支持通配符,*
代表任意数量个字符,?
代表单个字符
@
后面为库名,#
前为调用约定,其中用!
是__stdcall#
的缩写, {int}
代表返回值类型为int
例如:!{int}*::foo::bar(double)@x??
代表返回值为int
类型,调用约定为__stdcall
的方法foo::bar
,命名空间任意匹配,库名x??
代表x
开头,且为三个字符
valgrind
一起使用
--smc-check=all
选项禁用缓存来防止动态修改机器码(API HOOK技术)部分失效导致不可预期的错误valgrind
的特殊处理,暂时无法mock系统调用相关函数 (例如 gettimeofday
)支付宝 | 微信 | PayPal |