Appearance
声明式模式
声明式模式允许你仅声明 Mock 函数,通过 API 动态配置行为。
基本语法
c
// 仅声明,不提供函数体
__attribute__((mock))
返回类型 函数名(参数列表);配置返回值
使用 set_return() 设置返回值:
c
#include <anvil/mock.h>
__attribute__((mock))
int read_sensor(int sensor_id);
/*
* 设计说明:测试正常温度读取
* 预期结果:返回设定的温度值
*/
__attribute__((test_method))
int test_read_sensor(void) {
mock(read_sensor).set_return(42);
int temp = read_sensor(0);
return temp == 42;
}设置自定义实现
使用 set_custom() 设置自定义函数:
c
#include <anvil/mock.h>
__attribute__((mock))
int calculate(int a, int b);
// 自定义实现
int my_calculate(int a, int b) {
return a * b; // 返回乘积而不是默认行为
}
/*
* 设计说明:测试自定义计算逻辑
* 预期结果:使用乘法实现
*/
__attribute__((test_method))
int test_custom_calculate(void) {
mock(calculate).set_custom(my_calculate);
return calculate(3, 4) == 12;
}每次调用不同返回值
声明式模式默认每次调用返回相同值。如需不同返回值,使用用户实现模式或自定义函数:
c
#include <anvil/mock.h>
__attribute__((mock))
int get_next_value(void);
static int values[] = {1, 2, 3, 4, 5};
static int index = 0;
int sequential_value(void) {
if (index >= 5) return -1;
return values[index++];
}
__attribute__((test_initialize))
int setup(void) {
index = 0;
mock(get_next_value).set_custom(sequential_value);
return 0;
}
/*
* 设计说明:测试序列值
* 预期结果:依次返回1,2,3
*/
__attribute__((test_method))
int test_sequence(void) {
return get_next_value() == 1 &&
get_next_value() == 2 &&
get_next_value() == 3;
}与用户实现模式对比
| 特性 | 用户实现模式 | 声明式模式 |
|---|---|---|
| 函数体 | 必须提供 | 不提供 |
| 返回值控制 | 在函数体中 | set_return() |
| 自定义逻辑 | 直接编写 | set_custom() |
| 状态管理 | 手动 | 自动 |
| 适用场景 | 复杂逻辑 | 简单返回值 |
重置状态
每个测试前重置 Mock 状态:
c
__attribute__((test_initialize))
int setup(void) {
mock(read_sensor).reset();
mock(write_data).reset();
return 0;
}完整示例
c
#include "hardware.h"
#include <anvil/mock.h>
// 声明式 Mock
__attribute__((mock))
int hw_read_register(int addr);
__attribute__((mock))
int hw_write_register(int addr, int value);
__attribute__((mock))
int hw_init(void);
__attribute__((test_initialize))
int setup(void) {
mock(hw_read_register).reset();
mock(hw_write_register).reset();
mock(hw_init).reset();
// 默认配置
mock(hw_init).set_return(0); // 初始化成功
mock(hw_write_register).set_return(0); // 写入成功
return 0;
}
/*
* 设计说明:测试正常初始化流程
* 预期结果:初始化成功
*/
__attribute__((test_method))
int test_init_success(void) {
mock(hw_init).set_return(0);
int result = device_init();
return result == 0;
}
/*
* 设计说明:测试初始化失败处理
* 预期结果:硬件初始化失败时返回错误
*/
__attribute__((test_method))
int test_init_failure(void) {
mock(hw_init).set_return(-1);
int result = device_init();
return result == ERROR_HW_INIT;
}
/*
* 设计说明:测试寄存器读取
* 预期结果:读取正确的值
*/
__attribute__((test_method))
int test_read_register(void) {
mock(hw_read_register).set_return(0xABCD);
int value = device_read_status();
return value == 0xABCD;
}
/*
* 设计说明:验证写入操作
* 预期结果:正确的地址和值
*/
__attribute__((test_method))
int test_write_register(void) {
mock(hw_write_register).set_return(0);
device_write_config(0x1234);
// 验证调用参数
int addr = mock(hw_write_register).arg0_val;
int value = mock(hw_write_register).arg1_val;
return addr == CONFIG_REG && value == 0x1234;
}
// includes: -I../include何时使用声明式模式
适合使用声明式模式的场景:
- 只需要固定返回值
- 不需要复杂的状态管理
- Mock 逻辑简单
- 快速编写测试
适合使用用户实现模式的场景:
- 需要根据参数返回不同值
- 需要维护调用状态
- 需要执行副作用
- Mock 逻辑复杂