C++ Mock测试 Static Link Mock(静态链接期mock)

原理
可以使用gcc的链接选项 -Wl,–wrap=func。
会设置符号映射,在符号重定位阶段的时候,静态链接器对func函数的定位会定位到 __wrap_func 符号,对 __real_func 会定位到原func。

举例说明:

C Mock

libtest.h

/// @file libtest.h
#ifndef __LIBTEST_H__
#define __LIBTEST_H__

void test_func();
#endif

libtest.c

/// @file libtest.c
#include "libtest.h"
#include <stdio.h>

void test_func() {
	printf("test_func\n");
};

test.c

/// @file test.c
#include "libtest.h"

int main() {
	test_func();
	return 0;
};

wrap.c

/// @file wrap.c
#include <stdio.h>

void __real_test_func();
void __wrap_test_func() {
	printf("before test_func\n");
	__real_test_func();
};

编译

gcc -g -O0 libtest.c test.c wrap.c -o test -Wl,--wrap=test_func

结果为

before test_func
test_func

C++ Mock
由于C++对符号有修饰,故需要对修饰后的符号名做映射。

libtest.h

/// @file libtest.h
#ifndef __LIBTEST_H__
#define __LIBTEST_H__

void test_func();
#endif

libtest.cc

/// @file libtest.cc
#include "libtest.h"
#include <stdio.h>

void test_func() {
	printf("test_func\n");
};

test.cc

/// @file test.cc
#include "libtest.h"

int main() {
	test_func();
	return 0;
};

wrap.cc

/// @file wrap.cc
#include <stdio.h>

#ifdef __cplusplus
extern "C" {
#endif

void __real__Z9test_funcv();
void __wrap__Z9test_funcv() {
	printf("before test_func\n");
	__real__Z9test_funcv();
};

#ifdef __cplusplus
}
#endif

编译

g++ -g -O0 libtest.cc test.cc wrap.cc -o test -Wl,--wrap=_Z9test_funcv

结果为

before test_func
test_func

C++ 成员函数Mock
需要在实现的__wrap_func的函数中传入一个const*对象指针(即this),编译器会为非静态成员函数插入该参数。

C++规定,编译成员函数时要额外添加一个参数,把当前对象的指针传递进去,通过指针来访问成员变量。

libtest.h

/// @file libtest.h
#ifndef __LIBTEST_H__
#define __LIBTEST_H__

class Hello {
public:
	test_func();
};
#endif

libtest.cc

/// @file libtest.cc
#include "libtest.h"
#include <stdio.h>

void Hello::test_func() {
	printf("test_func\n");
};

test.cc

/// @file test.cc
#include "libtest.h"

int main() {
	Hello hello;
	hello.test_func();
	return 0;
};

wrap.cc

/// @file wrap.cc
#include <stdio.h>

#ifdef __cplusplus
extern "C" {
#endif

void __real__ZN5Hello9test_funcEv(const Hello* pointer);
void __wrap__ZN5Hello9test_funcEv(const Hello* pointer) {
	printf("before test_func\n");
	__real__ZN5Hello9test_funcEv(pointer);
};

#ifdef __cplusplus
}
#endif

编译

g++ -g -O0 libtest.cc test.cc wrap.cc -o test -Wl,--wrap=_ZN5Hello9test_funcEv

结果为

before test_func
test_func
发布了91 篇原创文章 · 获赞 5 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/LU_ZHAO/article/details/104269779