C++标准的单元测试

Unit tests for C++ criterion

我正在尝试根据我的 C++ 代码的标准进行单元测试,但我不知道如何测试只打印而不 return 任何内容的函数。这是我尝试过的:

//the function to test

#include <iostream>
#include <fstream>

void my_cat(int ac, char **av)
{
    if (ac <= 1)
        std::cout << "my_cat: Usage: ./my_cat file [...]" << std::endl;
    for (unsigned i = 1; i < ac; i += 1) {
        std::ifstream file (av[i]);
        if (file.fail()) {
            std::cout << "my_cat: ";
            std::cout << av[i];
            std::cout << ": No such file or directory" << std::endl;
        }
        else if (file.is_open()) {
            std::cout << file.rdbuf() << std::endl;
        }
        file.close();
    }
}
//the test
#include  <criterion/criterion.h>
#include  <criterion/redirect.h>

void my_cat(int ac, char **av);

Test(mycat, my_cat)
{
    char *av[] = {"./my_cat", "text.txt"};
    my_cat(2, av);
}

但是到了这里,我不知道用什么来检查打印是否正确。

有了gtest,我想这对你有帮助

testing::internal::CaptureStdout();
std::cout << "My test";
std::string output = testing::internal::GetCapturedStdout();

参考自:How to capture stdout/stderr with googletest?

另一个答案显示了如何使用 googletest 工具。但是,通常当您的代码难以测试时,那就是代码异味。考虑这个更简单的例子:

void foo(){
    std::cout << "hello";
}

当不直接使用 std::cout 而是传递要用作参数的流时,这更容易测试:

#include <iostream>
#include <sstream>

void foo(std::ostream& out){
    out << "hello";
}
    
int main() {
    std::stringstream ss;
    foo(ss);
    std::cout << (ss.str() == "hello");
}

一般来说,除了小玩具程序,我不建议直接使用std::cout。您永远不知道以后是否要写入文件或其他流。