tags:

views:

1081

answers:

5

I am using cxxtest as the test framework for my C++ classes, and would like to figure out a way to simulate sending data to classes which would normally expect to receive it from standard input. I have several different files which I would like to send to the classes during different tests, so redirection from the command line to the test suite executable is not an option.

Basically, what I would really like to do is find a way to redefine or redirect the 'stdin' handle to some other value that I create inside of my program, and then use fwrite() from these tests so that the corresponding fread() inside of the class pulls the data from within the program, not from the actual standard I/O handles associated with the executable.

Is this even possible? Bonus points for a platform-independent solution, but at a very minimum, I need this to work with Visual Studio 9 under Windows.

+9  A: 

The appropriate method is to rewrite your classes so that they are testable. They should accept as a parameter the handle, stream or file from which they are supposed to read data - in your test framework, you can then mock in the stream or supply the path to the file containing the test data.

1800 INFORMATION
+2  A: 

You should be able to use freopen() to point stdin to an arbitrary file.

Michael Burr
+2  A: 

I think you want your classes to use an input stream instead of std::cin directly. You'll want to either pass the input stream into the classes or set it on them via some method. You could, for exmaple, use a stringstream to pass in your test input:


std::istringstream iss("1.0 2 3.1415");
some_class.parse_nums(iss, one, two, pi);
Pat Notz
+3  A: 

rdbuf does exactly what you want. You can open a file for reading and replace cin's rdbuf with the one from the file. (see the link for a example using cout).

On unix-like OS you could close the 0 file handle (stdin) and open another file. It will have the lowest avaiable handle, which in this case would be 0. Or use one of posix calls that do exactly this. I'm not sure, but this may also work on Windows.

Kasprzol
+1  A: 

We can redirect cin in order it read data from a file. Here is an example :

#include <iostream>
#include <fstream>
#include <string>

int main()
{
    std::ifstream inputFile("Main.cpp");
    std::streambuf *inbuf = std::cin.rdbuf(inputFile.rdbuf());

    string str;
    // print the content of the file without 'space' characters
    while(std::cin >> str)
    {
        std::cout << str;
    }

    // restore the initial buffer
    std::cin.rdbuf(inbuf);
}
Rexxar