objective-c - C API 函数存在时的单元测试

标签 objective-c cocoa c-preprocessor ocunit

我的应用程序使用第三方 C API 来执行某些任务。我想知道如何对调用 API 的类进行单元测试,因为设置单元测试环境以使其正常工作是不切实际的。

举个例子。我的一个类可能有这样的方法:

- (id) doSomeStuff
{
    // my code
    // ...
    thirdPartyDoStuffFunction(17, 4);
    // etc...
}

对应的单元测试:

- (void) testDoSomeStuff
{
    MyClass *x = [[MyClass alloc] init];
    id result = [x doSomeStuff];

    STAssertNotNil(result, @"Result mustn't be nil");
}

假设由于我无法控制的原因,在运行单元测试目标时调用 ThirdPartyDoStuffFunction 将使测试崩溃。出于这个原因,并且因为我想确保使用正确的参数调用该函数,所以我想模拟它。

这是我迄今为止尝试过的:

  • Defining preprocessor macros将第三方函数重定向到它们的模拟版本。 然而,到目前为止我还无法做到这一点。首先,我尝试在单元测试目标的配置中定义一个预处理器常量 UNIT_TEST ,但该常量仅对我的单元测试类有效,对我正在测试的类无效。
  • 然后我发现了这个关于 creating a prefix header for the test target 的帖子,这似乎与第一种方法具有完全相同的效果:前缀头中定义的 UNIT_TEST 常量仅在测试类中可见,而不是被测试的类中可见。

更新:以上两种方法现在都适合我。他们没有这样做的原因似乎是被测类的实现文件(.m)尚未添加到单元测试目标中。添加它们后,宏就会按预期执行,即它们会覆盖第三方 API。

我仍然想知道为什么没有编译器/链接器错误,并且单元测试实际上运行了,而某些实现并不存在于其目标中,但重要的是它现在可以工作。

最佳答案

您应该创建一个包含以下内容的头文件TestRedirect.h:

#ifdef UNIT_TESTING

#define thirdPartyDoStuffFunction MyTest_thirdPartyDoStuffFunction
..........

#endif

您可以将此文件包含到您要测试的类的所有文件中。之后您创建 2 个不同的版本:

  • 带有编译器 key -DUNIT_TESTING用于测试;
  • 其他没有用于日常工作的 key 。

您的测试函数应简单地定义为MyTest_thirdPartyDoStuffFunction,并且它们应仅包含在测试配置中的链接中。

关于objective-c - C API 函数存在时的单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12026181/

相关文章:

Objective-C XMPPFramework 离线队列

ios - 如何从多目标应用程序中的特定 plist 获取字符串值?

macos - 适用于 Mac App Store 的应用程序在签名后无法运行

C++ 格式化字符串宏

目标名称的 Xcode/GCC 预定义宏?

c - 如何调试预处理器宏

ios - 设置 AFNetworking 3.x 单例请求和响应序列化

objective-c - Clojure 的协议(protocol)有影响吗?

cocoa - NIB 和 XIB Interface Builder 文件格式有什么区别?

ios - Obj-c,我可以使用协议(protocol)作为函数参数的一种参数类型吗?