如何为iOS TDD存根/模拟C函数?

5St*_*yan 6 c tdd objective-c ios

我目前正在创建一个TDD应用程序,但是我在测试应用程序所需的C函数的使用时遇到了问题.这是我需要测试的示例函数:

UIImageWriteToSavedPhotosAlbum(imageToBeSaved, nil, nil, nil)
Run Code Online (Sandbox Code Playgroud)

如何为TDD模拟或存根C方法?

Vic*_*lea 4

有几种方法可以做到这一点,但不如 OOP 语言那么漂亮。这里列出了我使用的:

使用函数指针

这种方法是我最喜欢的一种,因为在我看来它是最灵活的。

在头文件(*.h)中

int (*_fun) (int);

int fun (int a);

int fun_mock (int a);
Run Code Online (Sandbox Code Playgroud)

在测试用例文件(*.C)中

_fun = fun_mock;
Run Code Online (Sandbox Code Playgroud)

正常情况下文件(*.C)

_fun = fun;
Run Code Online (Sandbox Code Playgroud)

调用函数(main.C)

...
_fun ();
...
Run Code Online (Sandbox Code Playgroud)

编译

如果你想制作 TDD,你需要编译测试文件和主文件(或其余文件)。否则不编译测试文件。

使用宏来替换函数的名称

在头文件(*.h)中

如果你想打电话有趣

#define FUN fun

int fun (int a);

int fun_mock (int a);
Run Code Online (Sandbox Code Playgroud)

在头文件(*.h)中

如果你想调用mock版本

#define FUN fun_mock

int fun (int a);

int fun_mock (int a);
Run Code Online (Sandbox Code Playgroud)

调用函数(main.C)

...
FUN ();
...
Run Code Online (Sandbox Code Playgroud)

使用此方法,我们需要在编译任何模块之前设置正确的定义。

使用带有函数指针的结构

说实话,我从来没有使用过这种方法,但我在其他地方读过。主要思想是为模块的所有不同函数提供一个结构体指针,每当您想要更改函数时,只需更改该函数指针在该结构体上的地址即可。最后是与第一种方法类似的策略,但以不同的方式实现。

根据蒂莫西·琼斯的说法

test-dept 是一个相对较新的 C 单元测试框架,允许您对函数进行运行时存根。我发现它非常容易使用 - 这是他们文档中的一个示例:

void test_stringify_cannot_malloc_returns_sane_result() {
 replace_function(&malloc, &always_failing_malloc);
 char *h = stringify('h');
 assert_string_equals("cannot_stringify", h);
}
Run Code Online (Sandbox Code Playgroud)

尽管下载部分有点过时,但它的开发似乎相当活跃 - 作者很快修复了我遇到的问题。您可以通过以下方式获取最新版本(我一直在使用,没有出现问题):

svn checkout http://test-dept.googlecode.com/svn/trunk/ test-dept-read-only 上次更新的版本是 2011 年 10 月。

然而,由于存根是使用汇编程序实现的,因此可能需要一些努力才能使其支持 ARM。

我从/sf/answers/672967501/复制的最后一点。