2016-03-20 83 views
1

我需要爲以下函數編寫一些單元測試。爲了做到這一點,我需要模擬ifstream對象。我這樣做了,但在測試過程中遇到了執行控制問題。我如何設置在 while(p_fileDescriptor->get(l_singleByte))while(p_fileDescriptor->get(l_singleByte)) 中返回的值,以便在一種情況下將eofbit對象返回到另一個case中的「normal」istream對象?我嘗試了一些選項,但它不起作用。你能幫我解決嗎? 波紋管功能有我的單元測試。 功能測試:Google Mock:模擬fstream對象和測試執行控制

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); 
} 

回答

2

你的做法是不好的。 ifstream::get不是虛擬函數,所以嘲笑它沒有影響,你期望:基地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); 
} 

或者,更好的 - 你應該創建自己的抽象 - 定義接口,那是後話,它返回一個字節:

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

然後 - 實現了基於std::istream

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

Then Mock:

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

擁有這些類 - 只需更改您的實現和測試 - 它就可以工作。