gpt4 book ai didi

C 单元测试 - 从 stub 的优雅退出例程返回

转载 作者:太空狗 更新时间:2023-10-29 15:04:52 29 4
gpt4 key购买 nike

这是我遇到的情况。我正在测试的函数有一个错误条件,如果命中,调用一个正常的退出函数来释放任何全局内存、关闭句柄并退出程序。

显然,我想编写一个测试来触发这种情况,以确保它得到正确处理,但我不希望正常退出例程实际退出程序,因为这会停止任何剩余的测试。这意味着对优雅的退出例程进行 stub 。 stub 而不调用退出的问题是控制流返回到被测函数(这很糟糕,因为例程应该退出)。

真正的问题是:我们如何将控制权从 stub 函数返回到测试而不是被测试的函数?

我可以做一个 setjmp/longjmp,但由于“gotos”通常很糟糕,我希望得到任何其他建议。 (请记住,这是过程 C,而不是 C++,因此据我所知,异常不会起作用)

编辑正如 Soren 和其他人在下面所建议的那样,在测试时让 exit 什么都不做是一个好主意。有几种方法可以做到这一点,无论是通过 #define 语句还是 exit() 例程的 stub 。

但是,这样做提出了我真正想要解决的问题(setjmp/longjmp 除外)。看看这个场景:

void gracefulExit() {
// Clean Up
exit();
}

void routineUnderTest() {
// Do some calcs

if (someBadCondition == TRUE)
gracefulExit()

// Do some more calcs
}

如果 exit() 在这种情况下什么都不做,gracefulExit() 会将控制权返回给被测试的例程,这是不应该发生的。因此,我需要一种方法让 exit()(或 gracefulExit() 的 stub 版本)将控制权返回给测试而不是被测函数。

setjmp/longjmp(又名 goto)是一种实现此目的的方法,尽管不是一种真正优雅的方法。关于如何解决这个问题的任何想法?

编辑#2

如 fizzer 所述,setjmp/longjmp 是处理这种情况的有效方法。这是我将永久处理它的可能方式。

但是,我从同事那里收到了另一种可能的解决方案。不要将 gracefulExit() 例程定义为 stub 例程,而是执行以下操作:

#define gracefulExit return NULL

被测试的特定函数处理得很好,因为 NULL 是它的有效返回值。我还没有在所有可能的情况下对此进行测试(例如,具有 void 返回值的函数)。如前所述,我可能会使用 setjmp/longjmp 方法来解决这个问题,但如果这个额外的解决方案激发了某人的灵感,那就太好了!

最佳答案

我建议您的清理方法创建一个未发布的接口(interface)来执行退出操作。

所以

   void (*exitfunc((int) = exit;
void myCleanUp() {
.... do the cleanup
(*exitfunc)(-1); // this will in normal operation call exit
}

并且在您的单元测试代码中,您将退出函数“覆盖”为

   void donothing(int exitcode) {}
unittest(){
extern void (*exitfunc((int);
exitfunc = donothing; // or use a longjump if clean exit cannot be made without
... do the test.....

这意味着无论是在单元测试中还是在其他地方,您的代码都会编译成相同的结果,并且只有在执行单元测试时才会出现行为差异。使用条件编译进行单元测试的替代方案意味着您最终会得到 .o 文件,您不知道这些文件是用于测试还是用于生产,并且您的项目将会发生不好的事情。

关于C 单元测试 - 从 stub 的优雅退出例程返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6904769/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com