针对cin / cout的协议的单元测试 - 如何阻止流等待内容?

问题描述 投票:1回答:1

我正在尝试为一个程序编写单元测试,该程序需要通过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 ++中实现这一目标,或者更一般地说如何在进程间管道上单元测试协议?

提前感谢任何想法。

c++ io istream
1个回答
0
投票

std:::getline返回您为其提供的输入流对象作为参数。流本身将具有一个状态,用于确定是否应在布尔上下文中将其评估为truefalse。我让你的循环能够接受一个通用的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);
}
© www.soinside.com 2019 - 2024. All rights reserved.