c++ - 谷歌模拟 : mock fstream object and control of execution in test

标签 c++ unit-testing fstream googletest googlemock

我需要为以下功能编写一些单元测试。为此,我需要模拟 ifstream 对象。我这样做了,但是我在测试期间对执行的控制有问题。如何设置 get in 返回的值 while(p_fileDescriptor->get(l_singleByte)) 在一种情况下是 eofbit 对象,在另一种情况下是“普通”istream 对象?我尝试了一些选项,但没有用。你能帮我吗? 波纹管功能是我的单元测试。 要测试的功能:

void ServerSendFileRequestHandler::sendRequestedFile(std::shared_ptr<std::istream> p_fileDescriptor, int& p_clientSocket) const
{
unsigned int l_msgCounter = 1;
unsigned long long l_byteCounter = 0;
Message l_sendline;
memset(&l_sendline, 0, sizeof(l_sendline));

char l_singleByte;
while(p_fileDescriptor->get(l_singleByte))
{
    checkIfReadByteSucceded(p_fileDescriptor, l_byteCounter);
    l_sendline.payload[l_byteCounter] = l_singleByte;
    l_byteCounter++;

    if(l_byteCounter == PAYLOAD_SIZE)
    {
        std::cout << "Sending message number: " << l_msgCounter << std::endl;
        sendClientSendFileInd(l_sendline, l_byteCounter, p_clientSocket);
        l_msgCounter++;

        l_byteCounter = 0;
        memset(&l_sendline, 0, sizeof(l_sendline));
    }
}

if(l_byteCounter)
{
    std::cout << "Sending message number: " << l_msgCounter << std::endl;
    sendClientSendFileInd(l_sendline, l_byteCounter, p_clientSocket);
    l_msgCounter++;
}
std::cout << "Sending of file is done!" << std::endl;
}

我的单元测试:

#include "gmock/gmock.h"
#include <istream>
using namespace std;
class FstreamMock : public std::istream  
{
public:
    MOCK_METHOD1(get, istream&(char&));
};

using namespace testing;
TEST_F(ServerSendFileRequestHandlerTestSuite, sendRequestedFileTest)
{
    int l_clientSocket = 0;
    std::shared_ptr<FstreamMock> l_fileDescriptor;
    const bool i = false;

    char l_byte;
    //EXPECT_CALL(*l_fileDescriptor, get(_)).WillRepeatedly(ReturnRef(*l_fileDescriptor));
    EXPECT_CALL(*l_fileDescriptor, get(_)).WillRepeatedly(ReturnRef(*l_fileDescriptor);
    m_sut.sendRequestedFile(l_fileDescriptor, l_clientSocket);
}

最佳答案

你的方法不好。 ifstream::get不是虚函数,因此模拟它不会产生您期望的效果:调用 base ifstream::get

无论如何 - 你应该使用 istream 而不是 ifstream - 在函数 ServerSendFileRequestHandler::sendRequestedFile 中 - 为了测试你可以只使用 stringstream - 很容易断言写入stringstream 的内容。您可以将此函数名称更改为 ServerSendFileRequestHandler::sendRequestedStream

TEST_F(ServerSendFileRequestHandlerTestSuite, sendRequestedStreamTest)
{
    std::istringstream stream("some input");
    int l_clientSocket = 0;
    const bool i = false;

    char l_byte;
    m_sut.sendRequestedStream(stream, l_clientSocket);
}

或者,更好 - 你应该创建自己的抽象 - 定义你的接口(interface),即返回单字节的东西:

class IByteStream  
{
public:
    virtual ~IByteStream() = default;
    virtual char get() = 0;
};

Then - 基于std::istream的实现:

class StdStreamByteStream : public IByteStream  
{
public:
    StdStreamByteStream(std::istream& is) : is(is) {}        
    char get() override { return is.get(); }
private:
    std::istream& is;
};

然后模拟:

class ByteStreamMock : public IByteStream  
{
public:
    MOCK_METHOD0(get, char());
};

有了这些类 - 只需更改您的实现和测试 - 它就会起作用。

关于c++ - 谷歌模拟 : mock fstream object and control of execution in test,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36119525/

相关文章:

现有数据的 C++ STL vector

c++ - 词频程序-文件输入太大?

java - 如何处理单个简单测试用例将驱动整个实现的情况?

c++ - 流的 fscanf 类型函数?

c++ - Fstream 作为私有(private)成员访问

c++ - 使用 typedef 部分默认模板参数?

android - undefined reference 错误 - rand

c++ - Doxygen,图形类层次结构中没有显示任何内容

java - 将单元测试引入现有项目

带有解析器防护装置的 Angular 单元测试