首页 > 解决方案 > Google Test C 中的调试、系统函数(fopen、fclose、fread、fwrite、...)和 for 循环

问题描述

我正在使用 Google Test 测试 C 代码,但遇到了为系统函数编写存根的问题,例如:fopen、fclose、fread、fwrite、memcpy、memset、stat、...我不知道如何存根其输入/正确输出方便测试,无需关心真实数据。下面的例子:

bool open_file(void)
{
   FILE *srcfd;
   FILE *destfd;
   int dataLen;
   bool retVal=false;
   char buffer[255];
   srcfd = fopen("srcFileName", "r");
    if(NULL != srcfd)
    {
        destfd = fopen("destFileName", "w+");
        if(NULL != destfd)
        {
            retVal = true;

            while ((true == retVal) &&
                    ((dataLen = fread(buffer, sizeof(char), sizeof(buffer), srcfd)) > 0))
            {
                if (fwrite(buffer, sizeof(char), dataLen, destfd) != dataLen)
                {
                    retVal = false;
                }
            }

            fclose(destfd);

        }
        else
        {
            printf("%s: Failed to create file '%s'...\n",
                    __func__, "destFileName");
        }
        fclose(srcfd);
    }
    else
    {
        printf("%s: Failed to create file '%s'...\n", __func__, "srcFileName");
    }
return retVal;
}

标签: cunit-testinggoogletest

解决方案


您始终可以编写自己的外部函数(存根)定义来支持您的测试,而无需关心函数的实际实现。

为了让您的生活更轻松,您可以使用一些已经存在的存根框架,例如Fake Function Framework

在您的情况下,要使用您bool open_file(void)的存根进行测试,fopen可以在您的测试文件中执行以下操作:

#include "fff.h"
DEFINE_FFF_GLOBALS;
//fake fopen, be sure about the prototype of the faked function
FAKE_VALUE_FUNC(FILE*, fopen, const char*, const char*); 

And in the test case:

TEST_F(Test_open_file, stub_fopen){
   //call the function under test
   open_file();
   //check number of time fopen called
   ASSERT_EQ(fopen_fake.call_count, 1);
   //check input parameter
   ASSERT_EQ(strncmp(fopen_fake.arg0_val, "destFileName", 100), 0);
}

But be clear that stub is not always a good solution, do stub only when you really don't care about the real implementation of the external function and you just want the output of that function for your test purpose. Sometimes, call the real external function is better.

(I strike the bellowed texts because you modified your question)

You cannot control a local variable in the function under tested from your test case, you need to control it through global variables, function inputs or stub return value... whatever interfaces that set the value for that local variable you can interact with in your test cases.


推荐阅读