I'm trying to make unit tests with criterion for my C code but I can't figure out how to test a function that only print and do not return anything. Here's what I tried:
//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);
}
But now that I'm here I don't know what to use to check if the print is correct.
CodePudding user response:
With gtest, I think this can help you
testing::internal::CaptureStdout();
std::cout << "My test";
std::string output = testing::internal::GetCapturedStdout();
refer from : How to capture stdout/stderr with googletest?
CodePudding user response:
The other answer shows how to use a googletest facility. However, in general when your code is difficult to test, then that is a code smell. Consider this simpler example:
void foo(){
std::cout << "hello";
}
This is much easier to test when don't use std::cout
directly, but pass the stream to be used as parameter:
#include <iostream>
#include <sstream>
void foo(std::ostream& out){
out << "hello";
}
int main() {
std::stringstream ss;
foo(ss);
std::cout << (ss.str() == "hello");
}
In general, I do not recommend to use std::cout
directly for anything but small toy programs. You never know if later you want to write to a file or some other stream.