单元测试:生产代码和模拟实现的同居

时间:2017-01-31 19:10:03

标签: c unit-testing testing tdd

我知道关于测试双打,嘲笑等的基础知识,但我在测试以下内容方面遇到了问题

void funA(void) {
    /* do some stuff, using mocked functions from 3rd party library */
}

我已经为funA()编写了单元测试,检查了调用好的函数(使用他们的模拟实现)。 到目前为止,模拟函数是库函数。这不是我的代码。我不想测试他们原来的实现。

现在,我想测试这个功能

void funB(void) {
    /* do some complicated stuff, and call `funA()` on some situations */
}

如何确保从funA调用funB函数?我无法向funA添加虚假实现,我需要其生产代码才能对其进行测试。

我现在正在做的是确保funA正在调用的模拟正如我所期望的那样。但这不是一个好方法,因为我只是想重新测试funA,当我只想确保funB完成它的工作时。 / p>

1 个答案:

答案 0 :(得分:1)

在讨论之后(参见原始问题的评论),并与James Grenning(CppUTest的作者之一)进行简短的论坛交流,主要解决方案如下:

  • funA()funB()
  • 设置不同的测试版本
  • 使用函数指针动态更改行为

我不是这两种解决方案的忠实粉丝,但感觉我在C中做得不多。我最终会选择多种二进制解决方案。

作为参考,以下是James Grennings的答案:

  

您可能想在测试B()时模拟A()。

     

例如

     

如果我有一个message_dispatcher()从串口读取命令   端口通过getline(),getline()使用getc()和getc()使用IORead   和IOWrite。我可以模仿IORead和IOWrite并拥有一套   测试message_dispatcher()的可怕测试。

     

或者我可以使用模拟IORead()和IOWrite(),getline()来测试getc()   使用某种fake_getc()和测试message_dispatcher()   fake_getline()。如果您只使用链接器替换,则需要   三个测试构建。如果你使用函数指针,你可以做一个   测试构建。你也可以混合比赛。

     应使用IORead和IOWrite的链接时模拟测试

getc()   因为你的单元测试从不想要真正的IORead和IOWrite   脱靶测试(他们可能需要目标测试,但那些   将是集成测试。)

     

有很多种可能性。你也可以有一些其他的代码   getline()并将其提供给调度程序,删除其依赖项。