java打桩_C代码的打桩框架 - FFF (Fake Function Framework)

我只是IT圈的搬运工,项目原址外链网址已屏蔽

FFF是一个用宏实现的小框架,只需要一个头文件fff.h,没有任何其他依赖,非常简洁。

FFF的核心就是三个宏:

FAKE_VOID_FUNC(fn [,arg_types*]);

定义一个名为fn的桩函数,返回值为空,有n个参数。

FAKE_VALUE_FUNC(return_type, fn [,arg_types*]);

定义一个名为fn的桩函数,返回值类型为return_type,有n个参数。

RESET_FAKE(fn);

重置桩函数fn的调用信息。

实现上,FFF为桩生成了一系列变量。以带有返回值并且有一个参数的桩函数为例:

#define DECLARE_FAKE_VALUE_FUNC1(RETURN_TYPE, FUNCNAME, ARG0_TYPE) \

EXTERN_C \

typedef struct FUNCNAME##_Fake { \

DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \

DECLARE_ALL_FUNC_COMMON \

DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \

RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0); \

} FUNCNAME##_Fake;\

extern FUNCNAME##_Fake FUNCNAME##_fake;\

void FUNCNAME##_reset(); \

END_EXTERN_C \

DECLARE_ARG生成了存储当前参数值的变量和存储历史参数值的数组。

#define DECLARE_ARG(type, n, FUNCNAME) \

type arg##n##_val; \

type arg##n##_history[FFF_ARG_HISTORY_LEN];

DECLARE_ALL_FUNC_COMMON定义了桩被调用的次数,参数历史数组的长度以及调用HISTORY_DROPPED的次数。

#define DECLARE_ALL_FUNC_COMMON \

unsigned int call_count; \

unsigned int arg_history_len;\

unsigned int arg_histories_dropped; \

DECLARE_VALUE_FUNCTION_VARIABLES定义了桩函数返回值相关的数据。

custom_fake提供了一个回调接口,可以用自己的函数来构造返回值。

实例:

#include "UI.h"

#include "../../fff.h"

#include "SYSTEM.h"

#include "DISPLAY.h"

#include 

#include 

#include 

/* Test Framework :-) */

void setup();

#define TEST_F(SUITE, NAME) void NAME()

#define RUN_TEST(SUITE, TESTNAME) printf(" Running %s.%s: \n", #SUITE, #TESTNAME); setup(); TESTNAME(); printf(" SUCCESS\n");

DEFINE_FFF_GLOBALS;

/* SYSTEM.h */

FAKE_VOID_FUNC2(SYSTEM_register_irq, irq_func_t, unsigned int);

/* DISPLAY.h */

FAKE_VOID_FUNC(DISPLAY_init);

FAKE_VOID_FUNC(DISPLAY_clear);

FAKE_VOID_FUNC(DISPLAY_output, char *);

FAKE_VALUE_FUNC(unsigned int, DISPLAY_get_line_capacity);

FAKE_VALUE_FUNC(unsigned int, DISPLAY_get_line_insert_index);

FAKE_VOID_FUNC0(button_press_cbk);

/* Initialializers called for every test */

void setup()

{

RESET_FAKE(SYSTEM_register_irq);

RESET_FAKE(DISPLAY_init)

RESET_FAKE(DISPLAY_clear)

RESET_FAKE(DISPLAY_output)

RESET_FAKE(DISPLAY_get_line_capacity)

RESET_FAKE(DISPLAY_get_line_insert_index);

RESET_FAKE(button_press_cbk);

FFF_RESET_HISTORY();

DISPLAY_get_line_capacity_fake.return_val = 2;

}

/* Tests go here */

TEST_F(UITests, init_will_initialise_display)

{

UI_init();

assert(DISPLAY_init_fake.call_count == 1);

}

TEST_F(UITests, init_will_register_interrupt_gpio2)

{

UI_init();

assert(SYSTEM_register_irq_fake.call_count == 1);

assert(SYSTEM_register_irq_fake.arg0_val == UI_button_irq_handler);

assert(SYSTEM_register_irq_fake.arg1_val == IRQ_GPIO_2);

}

TEST_F(UITests, when_no_irq_then_missed_irq_counter_zero)

{

assert(UI_get_missed_irqs() == 0);

}

TEST_F(UITests, when_one_irq_and_no_handler_then_missed_irq_counter_one)

{

UI_button_irq_handler();

assert(UI_get_missed_irqs() == 1);

}

TEST_F(UITests, when_one_irq_and_valid_callback_then_missed_irq_counter_zero)

{

UI_init();

UI_register_button_cbk(button_press_cbk);

UI_button_irq_handler();

assert(UI_get_missed_irqs() == 0);

}

TEST_F(UITests, when_one_irq_and_valid_callback_then_callback_called)

{

UI_register_button_cbk(button_press_cbk);

UI_button_irq_handler();

assert(button_press_cbk_fake.call_count == 1);

}

TEST_F(UITests, write_line_outputs_lines_to_display)

{

char msg[] = "helloworld";

UI_write_line(msg);

assert(DISPLAY_output_fake.call_count == 1);

assert(strncmp(DISPLAY_output_fake.arg0_val, msg, 26) == 0);

}

TEST_F(UITests, when_no_empty_lines_write_line_clears_screen_and_outputs_lines_to_display)

{

DISPLAY_get_line_insert_index_fake.return_val = 2;

char msg[] = "helloworld";

UI_write_line(msg);

assert(DISPLAY_clear_fake.call_count == 1);

assert(DISPLAY_output_fake.call_count == 1);

// Check the order of the calls:  Don't care about the first two:

// DISPLAY_get_line_capacity and DISPLAY_get_line_insert_index

assert(fff.call_history_idx == 4);

assert(fff.call_history[2] == (void *) DISPLAY_clear);

assert(fff.call_history[3] == (void *) DISPLAY_output);

}

TEST_F(UITests, when_empty_lines_write_line_doesnt_clear_screen)

{

// given

DISPLAY_get_line_insert_index_fake.return_val = 1;

char msg[] = "helloworld";

// when

UI_write_line(msg);

// then

assert(DISPLAY_clear_fake.call_count == 0);

}

TEST_F(UITests, when_string_longer_than_26_then_truncated_string_output)

{

// given

char input[] = "abcdefghijklmnopqrstuvwxyz0123456789";

char expected[] = "abcdefghijklmnopqrstuvwxyz";

// when

UI_write_line(input);

// then

assert(strncmp(expected, DISPLAY_output_fake.arg0_val, 37) == 0);

}

TEST_F(UITests, when_outputting_to_full_display_then_previous_inserted)

{

// given

DISPLAY_get_line_insert_index_fake.return_val = 1;

char oldest[] = "oldest";

char newest[] = "newest";

// when

UI_write_line(oldest);

UI_write_line(newest);

// then

assert(DISPLAY_output_fake.call_count == 2);

// fills last line

assert(strncmp(oldest, DISPLAY_output_fake.arg0_history[0], 37) == 0);

//clears

assert(DISPLAY_clear_fake.call_count == 1);

// inserts old line at first

assert(strncmp(oldest, DISPLAY_output_fake.arg0_history[1], 37) == 0);

// then inserts new line

assert(strncmp(newest, DISPLAY_output_fake.arg0_history[2], 37) == 0);

}

int main()

{

setbuf(stdout, NULL);

fprintf(stdout, "-------------\n");

fprintf(stdout, "Running Tests\n");

fprintf(stdout, "-------------\n\n");

fflush(0);

/* Run tests */

RUN_TEST(UITests, init_will_initialise_display);

RUN_TEST(UITests, init_will_register_interrupt_gpio2);

RUN_TEST(UITests, when_no_irq_then_missed_irq_counter_zero);

RUN_TEST(UITests, when_one_irq_and_no_handler_then_missed_irq_counter_one);

RUN_TEST(UITests, when_one_irq_and_valid_callback_then_missed_irq_counter_zero);

RUN_TEST(UITests, when_one_irq_and_valid_callback_then_callback_called);

RUN_TEST(UITests, write_line_outputs_lines_to_display);

RUN_TEST(UITests, when_no_empty_lines_write_line_clears_screen_and_outputs_lines_to_display);

RUN_TEST(UITests, when_empty_lines_write_line_doesnt_clear_screen);

RUN_TEST(UITests, when_string_longer_than_26_then_truncated_string_output);

printf("\n-------------\n");

printf("Complete\n");

printf("-------------\n\n");

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值