c++ - 模拟流以进行测试

标签 c++ stream

来自 Get an istream from a char* ,我正在尝试为一些测试编写一个模拟流容器,如下所示:

struct mock_membuf : std::streambuf
{
    mock_membuf(char* begin, char* end) {
        this->setg(begin, begin, end);
    }
};

struct MockStreamContainer{
    explicit MockStreamContainer(char* buffer, int offset, int nbytes): m_sbuf(buffer + offset, buffer + offset + nbytes), m_body(&m_sbuf), m_size(nbytes) {}

    std::istream& Body() const {
        return m_body;
    }

    int Size() const {
        return m_size;
    }

    mock_membuf m_sbuf; // same as membuf from the question referenced
    std::istream& m_body;
    int64_t m_size;
};

并将按如下方式使用:

int main()
{
    char buffer[] = "I'm a buffer with embedded nulls\0and line\n feeds";

    auto get_stream = [&buffer](int offset, int nbytes) {
        return MockStreamContainer(buffer, offset, nbytes);
    };
    std::string line;
    auto r = get_stream(5, 10);
    std::istream& in = r.Body();
    while (std::getline(in, line)) {
        std::cout << "line: " << line << "\n";
    }
    return 0;
}

上面的代码只是我试过的(这里是一个 link )并且错误缠身 - 关于如何正确有效地实现它有什么建议吗?

附言根据要求,上述代码目前抛出以下编译错误:

main.cpp: In constructor 'MockStreamContainer::MockStreamContainer(char*, int, int)':

main.cpp:17:131: error: invalid initialization of non-const reference of type 'std::istream&' {aka 'std::basic_istream<char>&'} from an rvalue of type 'mock_membuf*'

     explicit MockStreamContainer(char* buffer, int offset, int nbytes): m_sbuf(buffer + offset, buffer + offset + nbytes), m_body(&m_sbuf), m_size(nbytes) {}

编辑: 多亏了@Martin York 的回答,我才能够通过做一个小改动来解决问题:将 m_body 转换为指针而不是引用。

最佳答案

你的成员变量m_body是一个引用:

std::istream&    m_body;
            ^     reference

所以你试图通过在构造函数中创建一个临时对象来初始化这个引用。

explicit MockStreamContainer(char* buffer, int offset, int nbytes):
    m_sbuf(buffer + offset, buffer + offset + nbytes),
    m_body(&m_sbuf),    // Here you are passing a pointer to `std::streambuf`
                        // This is not an `std::istream` so the compiler
                        // is trying to create one using the single argument
                        // constructor.
                        //
                        // That worked. So you have a temporary `std::istream` object
                        //
                        // You can not bind a temporary object to a non const reference
                        // hence the compiler error.
    m_size(nbytes)
{}

我会这样做:

#include <iostream>

struct mock_membuf : public std::streambuf
{
    mock_membuf(char* begin, char* end) {
        this->setg(begin, begin, end);
    }
};

struct mock_stream: public std::istream
{
    mock_membuf     streamBuffer;
    public:
        mock_stream(char* buffer, int offset, int nbytes)
            : std::istream(nullptr)
            , streamBuffer(buffer + offset, buffer + offset + nbytes)
        {
            rdbuf(&streamBuffer);
        }
};

int main()
{
    char buffer[] = "I'm a buffer with embedded nulls\0and line\n feeds";

    std::string line;
    mock_stream in(buffer, 5, 10);
    while (std::getline(in, line)) {
        std::cout << "line: " << line << "\n";
    }
    return 0;
}

关于c++ - 模拟流以进行测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53381777/

相关文章:

c++ - 调用 C++ 容器的 size() 函数的运行时间是多少

python - Scapy for C++ 的类似库

c++ - 为什么 stdfax.h 应该是 MFC 应用程序中的第一个包含文件?

c++ - 使用自定义 "front" vector 更新 "world up" vector 的正确方法是什么?

c++ - 使用 malloc 初始化一个类

C++流作为成员变量

windows - Windows 机器中的 dir/r 和输出流

node.js - Node JS。 Child_process.spawn。处理进程的输入提示

arrays - 检索 jq 结果作为一个列表对象,而不是一串成员

java - Java中有没有一种干净的方法将int数组的一部分输出为字符串?