Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing a functions whose purposes is side effects

How would you unit test 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);

}
like image 847
David Avatar asked May 06 '10 16:05

David


1 Answers

Instead of worrying about how to test the function as it stands, I'd redesign the function to work a bit more sensibly, and test the re-designed version instead.

Right now, the function seems to have three separate (and only slightly related) responsibilities: do a conversion, modify an externally supplied string, and write some data to a stream. The stream to which it writes (std::cout) is also hard-coded -- a problem waiting to happen (e.g., conversion to a GUI environment is likely to be non-trivial).

I'd start by 1) splitting it up into logical functions, and 2) supplying the stream as a parameter.

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;
}

I haven't included anything to (specifically) modify an externally supplied string -- obviously you can assign the return value from convert_int as you see fit, and the value of the string that was passed in wasn't being used anyway.

Truthfully, write_string is a good candidate to be eliminated entirely, but since you had that basic kind of capability, we'll retain it for the moment. Testing these is relatively simple -- for convert_int, we look at the string it returns, and compare to what we expect. For write_string, we can pass a stringstream instead of a normal ostream -- then we can use .str() to get that result as a string, and (again) compare to what we expect.

like image 105
Jerry Coffin Avatar answered Oct 19 '22 13:10

Jerry Coffin