如何对涉及IO的c函数进行单元测试?

时间:2012-12-25 08:24:30

标签: c unit-testing io mocking getchar

我在将单元测试写入涉及IO操作的C函数时遇到了问题。例如,下面是我编写的代码,用于从控制台获取用户的输入字符串。我不知道如何使用getchar()函数自动测试用户输入。

char * GetStringFromConsole()
{

    char *strToReturn = NULL;
    int len = 128;

    strToReturn = (char*)malloc(len);
    if (strToReturn) 
    {
        int ch;
        char *ptr  = strToReturn;
        int counter = 0;
        for (; ;) 
        {
            ch = getchar();
            counter++;

            if (counter == len)
            {
                strToReturn = realloc(strToReturn, len*=2 );
                ptr = strToReturn + counter-1;
            }

            if ((ch != EOF) && (ch != '\n') && (counter < len))
            {
                *ptr++ = ch;
            }
            else 
            {
                break;
            }

        }
        *ptr = '\0';
    }
    return strToReturn;
}   

1 个答案:

答案 0 :(得分:5)

模拟getchar

  1. 使用预处理器,例如在你的测试文件中。

    #define getchar mock_getchar
    #include "GetStringFromConsole.h"
    ...
    const char* mock_getchar_data_ptr;
    char mock_getchar()
    {
        return *mock_getchar_data_ptr++;
    }
    ...
    // in test function
    mock_getchar_data_ptr = "hello!\n";
    YourAssertEquals("hello", GetStringFromConsole());
    
  2. 链接器的替换符号(在我看来更难),例如在源.c文件中的某处定义您自己的getchar,而不是链接到stdlib(例如Windows上的msvcrt)

  3. 修改测试中的函数以接受返回char的函数,最佳选择(恕我直言) - 与 stdlib 无冲突。并通过在测试代码中从点 1 传递mock_getchar之类的东西来设置测试。

    typedef char (*getchartype)();
    char * GetStringFromConsole(getchartype mygetchar)
    {
        ...
        c  = mygetchar()
    
  4. 对于分数 1 2 ,我建议使用您自己的函数而不是getchar(例如mygetchar) - 这样您就可以了可以模拟/替换它而不会与std includes / libs发生冲突。