2

我正在使用 cmocka 对我的 C 项目进行一些单元测试,我想知道如何处理静态元素。

静态元素适合我:

  1. 声明为静态的函数
  2. 声明为静态的函数内的变量

所以让这个函数fut成为我们被测试的函数,并foo成为另一个函数。两者都放在文件中bar.c

static int fut(int add) {
  static int sum = 0;
  sum += add;
  return sum;
} 

int foo(int someVar){
  //Some calculation on someVar...
  someVar = someVar * 42;

  //call subRoutine
  return fut(someVar);
 }

让 foo.h 看起来像这样:

extern int foo(int someVar);

所以让我们继续,我将展示问题。我想通过两个独立的测试来测试被测函数,这些测试传递了一些随机值add。测试例程放在 main.c 中,如下所示:

void fut_test_1(void **state) {
  int ret;
  ret = fut(15);
  assert_int_equal(ret, 15);
  ret = fut(21);
  assert_int_equal(ret, 36);
}

void fut_test_2(void **state) {
  int ret;
  ret = fut(32);
  assert_int_equal(ret, 32);
  ret = fut(17);
  assert_int_equal(ret, 49);
}

现在我可以尝试使用以下代码编译单元测试: gcc main.c foo.c -Icmocka

现在有两个问题:

  1. 声明为 static 的函数无法从 访问main.c,因此链接器将在构建过程中停止。

  2. 函数内部声明为静态的变量不会在两次测试之间重置。所以fut_test_2会失败。

如何处理上述静态元素的这些问题?

4

1 回答 1

1

根据@LPs 的评论和我自己的想法,我想总结出可能的解决方案:

关于函数声明为静态的问题一:

  1. 一种解决方案是将源文件bar.c包含main.c#include "foo.c".
  2. 测试可以放置在其中,fut_test_2然后包含:被测函数和测试。然后可以通过将声明添加到以下位置来访问测试:fut_test_2bar.cfutfoo.h

    extern int foo(int someVar);
    extern void fut_test_1(void **state);
    extern void fut_test_2(void **state);
    

关于静态变量的问题:

  1. 这对测试来说并不容易。唯一的可能性是通过以下一种方式来扩大静态变量的可见性:
    • 通过将其移出fut
    • 让它在全球范围内
    • 使用一些 getter 和 setter 方法
  2. 只编写不需要在测试过程中重置静态变量的函数。
于 2017-02-10T09:36:15.927 回答