Skip to content

声明式模式

声明式模式允许你仅声明 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 逻辑复杂

本页面内容遵循 Luna 软件源代码授权条款 (LSLA) 发布