我正在尝试为一个程序编写单元测试,该程序需要通过cin / cout管道通过协议与另一个进程通信。当使用键盘或其他程序发送和接收命令和响应进行激励和测试时,它可以很好地工作。
在单元测试中,我显然需要将cin / cout替换为我可以发送和接收数据的其他流。 (通过另一个线程并写入协议处理程序的输入流)
不幸的是,我找不到一种方法来获取阻塞读取方法,该方法等待流获取更多内容。
使用cin时,下面的代码工作正常。
void Handler::loop() {
string cmd, token;
do {
cout << "HANDLER WAIT FOR COMMAND:" << endl;
// Block here waiting for input or EOF
// only blocks on cin!!
if (!getline(*pInputStream, cmd)) cmd = "quit";
// create the stream object
istringstream inStream(cmd);
inStream >> skipws >> token;
cout << "HANDLER RECEIVED: " << token << endl;
if (token == "quit") break;
// handle commands...
else if (token == "noop") /* noop */;
else cerr << "Unknown command: " << token << endl;
cout << "HANDLER COMMAND PROCESSED: " << token << endl;
} while (token != "quit");
}
使用时
istringstream is;
而不是cin然后'getline(* pInputStream,cmd)'不再阻止并立即返回-1。我找不到任何能够实现我所需要的其他方法(如果已经做了一段时间的研究)。
在Java中我实现了它:
final BufferedReader in =
new BufferedReader(newnputStreamReader(inputStream));
while (running) {
try {
// wait until a line is ready to be read
final String readLine = in.readLine();
...
这适用于System.in或其他流。 in.readline()始终阻塞,直到内容可用。非常适合单元测试。
具体而言,如何在C ++中实现这一目标,或者更一般地说如何在进程间管道上单元测试协议?
提前感谢任何想法。
std:::getline
返回您为其提供的输入流对象作为参数。流本身将具有一个状态,用于确定是否应在布尔上下文中将其评估为true
或false
。我让你的循环能够接受一个通用的std::istream
,所以它可以用std::cin
和其他istreams进行测试。第一次运行使用std::cin
,第二次使用std::istringstream
来表明它有效。
#include <iostream>
#include <sstream>
#include <iomanip>
void loop(std::istream& is) {
std::cout << "-----------------------------\n";
std::string cmd, token;
do {
std::cout << "HANDLER WAIT FOR COMMAND:\n";
// Block here waiting for input or EOF
// only blocks on cin!!
if(!getline(is, cmd)) cmd = "quit";
// create the stream object
std::istringstream inStream(cmd);
inStream >> std::skipws >> token;
std::cout << "HANDLER RECEIVED: " << token << "\n";
if(token == "quit") break;
// handle commands...
else if(token == "noop") /* noop */
;
else
std::cerr << "Unknown command: " << token << "\n";
std::cout << "HANDLER COMMAND PROCESSED: " << token << "\n";
} while(token != "quit");
}
int main() {
loop(std::cin);
std::istringstream ss("unknown\nnoop\nquit\nafter quit\n");
loop(ss);
}