lcut单元测试框架在我的项目中应用已经有一段时间了,项目组的同事对lcut的使用也是越来越熟悉,这不今天一位同事还提出了一个新需求,需求大致是这样的。

 
在实际项目中,经常遇到这类情况:
 
int bar(…) {
    int ret;
 
    ret = foo(…);
    /* assert ret */
    …
 
    ret = foo(…);
    /* assert ret */
    …
 
    ret = foo(…);
    /* assert ret */
    …
}
 
上述代码中被测函数接口bar的实现中多次调用了某函数foo。这样当我们用mock方式测试bar这个函数时,可能需要多次重复设置foo的返回值以及输出函数的值,就像这样:
 
void tc_test_bar_return_ok(lcut_tc_t *tc, void *data) {
    LCUT_RETV_RETURN(foo, 0);
    LCUT_RETV_RETURN(foo, 0);
    LCUT_RETV_RETURN(foo, 0);
 
    LCUT_ARG_RETURN(foo, 1);
    LCUT_ARG_RETURN(foo, 1);
    LCUT_ARG_RETURN(foo, 1);
 
    LCUT_INT_EQUAL(tc, 0, bar(…));
    …
}
 
我的同事希望lcut能提供一个接口:支持一次调用,设置多次mock obj的返回值或输出参数,使用这样的接口后,上述代码就可以简化为:
 
void tc_test_bar_return_ok(lcut_tc_t *tc, void *data) {
    LCUT_RETV_RETURN_COUNT(foo, 0, 3);
    LCUT_ARG_RETURN_COUNT(foo, 1, 3);
 
    LCUT_INT_EQUAL(tc, 0, bar(…));
}
 
这个需求提的非常好,看起来更像是一种语法糖(syntactic sugar),用于简化代码编写。于是乎下午我就为lcut增加了两个有用的宏:LCUT_RETV_RETURN_COUNT和LCUT_ARG_RETURN_COUNT。
 
正如上面所说,这两个宏可在一次调用中多次设置某个mock obj的返回值和输出参数值,两个宏的原型如下:
 
#define LCUT_RETV_RETURN_COUNT(fcname, value, count) do { \
        lcut_mock_obj_return(#fcname, (void*)value, __FUNCTION__, __LINE__, __FILE__, MOCK_RETV, count); \
    } while(0);
 
#define LCUT_ARG_RETURN_COUNT(fcname, value, count) do { \
        lcut_mock_obj_return(#fcname, (void*)value, __FUNCTION__, __LINE__, __FILE__, MOCK_ARG, count); \
    } while(0);
 
只是比之前提供的LCUT_RETV_RETURN和LCUT_ARG_RETURN多了一个宏参数count。count用于指出对mocked obj进行多少次返回值或输出参数的设置。
 
另外当count传入-1时,其语义为无论mocked object被使用多少次,其返回值或输出参数值都是一样的,即使用LCUT_RETV_RETURN_COUNT或LCUT_ARG_RETURN_COUNT时设置的那个值,直到下一次调用这两个宏进行重新设置时,值才会发生变化。例如上面的例子我们也可以改写为:
 
void tc_test_bar_return_ok(lcut_tc_t *tc, void *data) {
    LCUT_RETV_RETURN_COUNT(foo, 0, -1);
    LCUT_ARG_RETURN_COUNT(foo, 1, -1);
 
    LCUT_INT_EQUAL(tc, 0, bar(…));
}
 
这样无论后续再调用多少次bar函数,foo的返回值总是0,输出参数也总是1。
 
增加了这两个宏后,lcut的版本号也小升了一位,最新版本是lcut-0.3.0-rc1,其中还增加了一个针对lcut mock功能的example – mock_test.c。同时Google Code上的lcut guide也做了更新,对新增的宏的用法进行了简要说明。
 
就这样,lcut 0.3.0版本算是发布了,后续还会经过内部的细致测试,如果没有什么问题,就会去掉rc。

© 2012, bigwhite. 版权所有.

Related posts:

  1. lcut增加对mock的支持
  2. 发布一款轻量级C语言单元测试框架
  3. 关于宏定义切换以及屏蔽的例子
  4. 使用autoconf解决可移植性问题
  5. P.J.Plauger版本C标准库实现分析之'assert.h'