Appearance
用户实现模式
用户实现模式允许你提供完整的 Mock 函数体,完全控制函数行为。
基本语法
c
__attribute__((mock))
返回类型 函数名(参数列表) {
// 用户提供的实现
return 返回值;
}简单示例
c
#include <anvil/mock.h>
// Mock 传感器读取函数
__attribute__((mock))
int read_sensor(int sensor_id) {
return 42; // 始终返回 42
}使用静态变量控制返回值
c
#include <anvil/mock.h>
static int mock_temperature = 25;
__attribute__((mock))
int read_sensor(int sensor_id) {
return mock_temperature;
}
/*
* 设计说明:测试正常温度
* 预期结果:25度正常
*/
__attribute__((test_method))
int test_normal_temp(void) {
mock_temperature = 25;
return check_temp(0) == TEMP_NORMAL;
}
/*
* 设计说明:测试高温告警
* 预期结果:90度触发告警
*/
__attribute__((test_method))
int test_high_temp(void) {
mock_temperature = 90;
return check_temp(0) == TEMP_HIGH;
}模拟错误条件
c
#include <anvil/mock.h>
static int mock_return_error = 0;
__attribute__((mock))
int read_file(const char *path, char *buf, int size) {
if (mock_return_error) {
return -1; // 模拟读取错误
}
strcpy(buf, "mock data");
return 9;
}
/*
* 设计说明:测试文件读取错误处理
* 预期结果:读取失败时返回错误码
*/
__attribute__((test_method))
int test_file_read_error(void) {
mock_return_error = 1;
int result = process_file("test.txt");
mock_return_error = 0;
return result == ERROR_READ_FAILED;
}调用原始实现
使用 mock(func).call_real(...) 调用原始函数:
c
#include <anvil/mock.h>
static int call_count = 0;
__attribute__((mock))
int expensive_calculation(int x) {
call_count++;
// 前两次使用缓存值
if (call_count <= 2) {
return 100;
}
// 之后调用真实实现
return mock(expensive_calculation).call_real(x);
}验证调用参数
结合 Mock API 验证参数:
c
#include <anvil/mock.h>
__attribute__((mock))
int send_data(const char *host, int port, const char *data) {
return 0; // 成功
}
/*
* 设计说明:验证发送参数正确
* 预期结果:应使用正确的主机和端口
*/
__attribute__((test_method))
int test_send_params(void) {
mock(send_data).reset();
do_send("example.com", 8080, "hello");
// 验证参数
const char *host = *(const char **)mock(send_data).arg(0);
int port = mock(send_data).arg1_val;
return strcmp(host, "example.com") == 0 && port == 8080;
}带状态的 Mock
c
#include <anvil/mock.h>
static int sensor_values[] = {20, 25, 30, 35, 40};
static int read_index = 0;
__attribute__((mock))
int read_sensor(int id) {
if (read_index >= 5) {
return -1; // 没有更多数据
}
return sensor_values[read_index++];
}
__attribute__((test_initialize))
int setup(void) {
read_index = 0; // 重置索引
return 0;
}
/*
* 设计说明:测试连续读取
* 预期结果:应依次返回预设值
*/
__attribute__((test_method))
int test_sequential_read(void) {
return read_sensor(0) == 20 &&
read_sensor(0) == 25 &&
read_sensor(0) == 30;
}完整示例
c
#include "network.h"
#include <anvil/mock.h>
#include <string.h>
// Mock 状态
static int mock_connect_result = 0;
static int mock_send_result = 0;
static char mock_recv_data[256] = "";
// Mock 网络连接
__attribute__((mock))
int net_connect(const char *host, int port) {
return mock_connect_result;
}
// Mock 发送数据
__attribute__((mock))
int net_send(int fd, const char *data, int len) {
if (mock_send_result < 0) {
return mock_send_result;
}
return len; // 返回发送的字节数
}
// Mock 接收数据
__attribute__((mock))
int net_recv(int fd, char *buf, int len) {
int data_len = strlen(mock_recv_data);
if (data_len == 0) {
return 0;
}
strncpy(buf, mock_recv_data, len);
return data_len < len ? data_len : len;
}
__attribute__((test_initialize))
int setup(void) {
mock_connect_result = 0;
mock_send_result = 0;
mock_recv_data[0] = '\0';
mock(net_connect).reset();
mock(net_send).reset();
mock(net_recv).reset();
return 0;
}
/*
* 设计说明:测试正常通信流程
* 预期结果:发送请求后收到响应
*/
__attribute__((test_method))
int test_normal_communication(void) {
strcpy(mock_recv_data, "HTTP/1.1 200 OK");
char response[256];
int result = http_get("example.com", 80, "/", response, 256);
return result == 0 && strstr(response, "200 OK") != NULL;
}
/*
* 设计说明:测试连接失败处理
* 预期结果:连接失败时返回错误码
*/
__attribute__((test_method))
int test_connect_failure(void) {
mock_connect_result = -1;
char response[256];
int result = http_get("example.com", 80, "/", response, 256);
return result == ERROR_CONNECT_FAILED;
}
// includes: -I../include