【问题标题】:Unit testing in presence of C API functions存在 C API 函数的单元测试
【发布时间】:2023-03-03 20:53:02
【问题描述】:

我的应用程序使用第三方 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。

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

【问题讨论】:

  • 请改进您的帖子。目前尚不清楚哪些课程是您的课程,哪些课程不是。提供样品。
  • 做了一些清理和充实;也许这会让事情更清楚
  • 您是否尝试使用 OCMock 之类的模拟框架对其进行模拟?
  • 我看过了,但我相信它只能模拟 objc 对象,不能模拟 C 函数。如果我错了,请纠正我!

标签: objective-c cocoa c-preprocessor ocunit


【解决方案1】:

你应该创建一个头文件TestRedirect.h,内容如下:

#ifdef UNIT_TESTING

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

#endif

您将此文件包含在您要测试的类的所有文件中。之后,您创建 2 个不同的构建:

  • 使用编译器密钥-DUNIT_TESTING 进行测试;
  • 其他没有用于常规工作的钥匙。

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

【讨论】:

  • 现在对我有用。问题是尚未将实现文件添加到单元测试目标中(请参阅问题的编辑)。谢谢!
猜你喜欢
  • 2012-01-22
  • 2017-07-29
  • 2021-07-20
  • 1970-01-01
  • 2018-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多