Appearance
Mock API 参考
完整的 Anvil Mock API 文档。
头文件
c
#include <anvil/mock.h>API 汇总
| API | 用途 | 返回类型 |
|---|---|---|
mock(func).call_count | 获取调用次数 | int |
mock(func).arg(n) | 获取第 n 个参数(void*) | void* |
mock(func).argN_val | 获取第 N 个参数值 | 参数类型 |
mock(func).history(i, n) | 获取历史调用参数 | void* |
mock(func).reset() | 重置 Mock 状态 | void |
mock(func).call_real(...) | 调用原始实现 | 函数返回类型 |
mock(func).set_return(val) | 设置返回值 | void |
mock(func).set_custom(fn) | 设置自定义实现 | void |
调用追踪
call_count
获取 Mock 函数被调用的次数:
c
mock(read_sensor).reset();
read_sensor(0);
read_sensor(1);
read_sensor(2);
int count = mock(read_sensor).call_count; // count = 3arg(n)
获取最后一次调用的第 n 个参数,返回 void*:
c
send_data("hello", 5);
const char *data = *(const char **)mock(send_data).arg(0); // "hello"
int len = *(int *)mock(send_data).arg(1); // 5类型转换
arg(n) 返回 void*,需要手动转换类型。对于简单类型,推荐使用 argN_val。
argN_val
类型安全地获取第 N 个参数值(N = 0, 1, 2, ...):
c
send_data("hello", 5, 1);
// 直接获取值,无需类型转换
int len = mock(send_data).arg1_val; // 5
int flag = mock(send_data).arg2_val; // 1支持的参数索引:arg0_val, arg1_val, arg2_val, ..., arg9_val
history(i, n)
获取第 i 次调用的第 n 个参数:
c
read_sensor(10);
read_sensor(20);
read_sensor(30);
// 获取历史调用参数
int first_id = *(int *)mock(read_sensor).history(0, 0); // 10
int second_id = *(int *)mock(read_sensor).history(1, 0); // 20
int third_id = *(int *)mock(read_sensor).history(2, 0); // 30状态控制
reset()
重置 Mock 状态,清除调用计数和参数历史:
c
mock(read_sensor).reset();
// call_count 变为 0
// 参数历史被清空最佳实践
在 test_initialize 中重置所有 Mock:
c
__attribute__((test_initialize))
int setup(void) {
mock(func1).reset();
mock(func2).reset();
return 0;
}call_real(...)
调用原始函数实现:
c
__attribute__((mock))
int calculate(int x, int y) {
// 记录调用
log_call(x, y);
// 调用原始实现
return mock(calculate).call_real(x, y);
}行为配置(声明式模式)
set_return(val)
设置 Mock 函数的返回值:
c
__attribute__((mock))
int read_sensor(int id);
mock(read_sensor).set_return(42);
int value = read_sensor(0); // value = 42set_custom(fn)
设置自定义实现函数:
c
__attribute__((mock))
int calculate(int a, int b);
int my_impl(int a, int b) {
return a * b;
}
mock(calculate).set_custom(my_impl);
int result = calculate(3, 4); // result = 12完整示例
c
#include "network.h"
#include <anvil/mock.h>
__attribute__((mock))
int net_send(int fd, const char *data, int len);
__attribute__((mock))
int net_recv(int fd, char *buf, int len);
__attribute__((test_initialize))
int setup(void) {
mock(net_send).reset();
mock(net_recv).reset();
return 0;
}
/*
* 设计说明:验证发送次数
* 预期结果:应调用 send 3 次
*/
__attribute__((test_method))
int test_send_count(void) {
mock(net_send).set_return(5);
batch_send(3, "hello");
return mock(net_send).call_count == 3;
}
/*
* 设计说明:验证发送参数
* 预期结果:参数正确
*/
__attribute__((test_method))
int test_send_params(void) {
mock(net_send).set_return(5);
do_send(10, "test", 4);
int fd = mock(net_send).arg0_val;
const char *data = *(const char **)mock(net_send).arg(1);
int len = mock(net_send).arg2_val;
return fd == 10 &&
strcmp(data, "test") == 0 &&
len == 4;
}
/*
* 设计说明:验证历史调用
* 预期结果:每次调用参数正确
*/
__attribute__((test_method))
int test_send_history(void) {
mock(net_send).set_return(1);
net_send(1, "a", 1);
net_send(2, "b", 1);
net_send(3, "c", 1);
int fd1 = *(int *)mock(net_send).history(0, 0);
int fd2 = *(int *)mock(net_send).history(1, 0);
int fd3 = *(int *)mock(net_send).history(2, 0);
return fd1 == 1 && fd2 == 2 && fd3 == 3;
}
// includes: -I../include生成的文件位置
Mock 代码生成在临时目录:
/tmp/anvil-mocks/<测试文件名>/
├── __anvil_mock_net_send.c
├── __anvil_mock_net_recv.c
└── ...使用 anvil -c 保留这些文件用于调试。