单元测试其目的是副作用的函数

Dav*_*vid 5 c++ unit-testing

你会如何对do_int_to_string_conversion进行单元测试?

#include <string>
#include <iostream>

void do_int_to_string_conversion(int i, std::string& s) {
    switch(i) {
    case 1:
        s="1";
        break;
    case 2:
        s="2";
        break;
    default:
        s ="Nix";
    }
}

int main(int argc, char** argv){
    std::string little_s;

    do_int_to_string_conversion(1, little_s);
    do_int_to_string_conversion(2, little_s);
    do_int_to_string_conversion(3, little_s);

}
Run Code Online (Sandbox Code Playgroud)

Jer*_*fin 11

我没有担心如何测试它的功能,而是重新设计了更合理的功能,并测试了重新设计的版本.

现在,该函数似乎有三个独立的(并且只是略微相关)职责:进行转换,修改外部提供的字符串,并将一些数据写入流.它写入的流(std::cout)也是硬编码的 - 等待发生的问题(例如,转换到GUI环境可能是非平凡的).

我首先将1)分成逻辑函数,然后2)将流作为参数提供.

std::string convert_int(int val) {
    switch (val) { 
       case 1: return "1";
       case 2: return "2";
       default: return "Nix";
   }
}

std::ostream &write_string(std::ostream &os, std::string const &s) { 
    return os << s;
}
Run Code Online (Sandbox Code Playgroud)

我没有包含任何内容(特别是)修改外部提供的字符串 - 显然你可以根据需要分配返回值convert_int,并且无论如何都没有使用传入的字符串的值.

说实话,write_string完全被淘汰是一个很好的候选人,但既然你有这种基本的能力,我们暂时保留它.测试它们相对简单 - 因为convert_int,我们查看它返回的字符串,并与我们的预期进行比较.因为write_string,我们可以传递一个stringstream而不是正常ostream- 然后我们可以用来.str()将结果作为字符串,并(再次)与我们期望的进行比较.


Mat*_*eer 9

我想这只是一个例子.为什么不能在每次调用后断言little_s的值?

do_int_to_string_conversion(1, little_s);
assert_are_equal("1", little_s);
Run Code Online (Sandbox Code Playgroud)