11

我在为涉及 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;
}   
4

1 回答 1

6

模拟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. 链接器的替换符号(在我看来更难),例如getchar在源 .c 文件中的某个位置定义您自己的符号,而不是链接到 stdlib(例如 Windows 上的 msvcrt)

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

    typedef char (*getchartype)();
    char * GetStringFromConsole(getchartype mygetchar)
    {
        ...
        c  = mygetchar()
    

对于第 1点和第 2点,我建议使用您自己的函数而不是getchar(例如mygetchar) - 这样您就可以模拟/替换它而不会遇到与 std 包含/库的冲突。

于 2012-12-28T06:53:22.033 回答