As per Patterns for unit testing a C++ method that makes a standard library call, I'm test-driving development of a network-abstracting class. In order to unit test code that makes standard C library calls (which I can't mock) to handle BSD sockets, I've defined an interface ISocket
from which both my real implementation CSocket
and mock MockSocket
inherit.
Now I write my first unit test for the Network
class, which uses an ISocket
for the heavy lifting:
#include "gmock/gmock.h"
#include "gtest/gtest.h"
// C standard library includes omitted
#include "MockSocket.h"
#include "Network.h"
using ::testing::Return;
namespace JrStream {
class NetworkTest : public ::testing::Test {
protected:
Network net;
ISocket * socket_ptr;
virtual void SetUp() {
socket_ptr = new MockSocket();
}
};
TEST_F(NetworkTest, InitCallsSocket) {
EXPECT_CALL((MockSocket)*socket_ptr, Socket(AF_INET, SOCK_STREAM, 0))
.Times(1)
.WillOnce(Return(5)); //fake file descriptor
ASSERT_TRUE(net.init(socket_ptr));
}
} // namespace
// gtest boilerplate main() omitted
But I get this error on compilation:
g++ -g -Wall -Lgtest-1.5.0/lib -Igmock-1.5.0/include -Igtest-1.5.0/include -I.. -I../../Debug/src -c -o NetworkTest.o NetworkTest.cc
NetworkTest.cc: In member function ‘virtual void JrStream::NetworkTest_InitCallsSocket_Test::TestBody()’:
NetworkTest.cc:35: error: no matching function for call to ‘JrStream::MockSocket::MockSocket(JrStream::ISocket&)’
MockSocket.h:16: note: candidates are: JrStream::MockSocket::MockSocket()
MockSocket.h:16: note: JrStream::MockSocket::MockSocket(const JrStream::MockSocket&)
And here is what my interface and mock look like:
namespace JrStream {
class ISocket {
virtual int Socket(int domain, int type, int protocol) = 0;
};
}
#include "gmock/gmock.h"
#include "ISocket.h"
namespace JrStream {
class MockSocket: public JrStream::ISocket {
MOCK_METHOD3(Socket, int(int domain, int type, int protocol));
};
}
Any ideas what I'm doing wrong here?
Looks like you're invoking the copy constructor for MockSocket somewhere in TestBody without a cast.
I finally got it sorted. What was tripping me up is that I wanted to use a pointer, but googlemock works with classes. Here's what works:
#include "gmock/gmock.h"
#include "gtest/gtest.h"
// C standard library includes omitted
#include "MockSocket.h"
#include "Network.h"
using ::testing::Return;
namespace JrStream {
class NetworkTest : public ::testing::Test {
protected:
Network net;
MockSocket sock;
};
TEST_F(NetworkTest, InitCallsSocket) {
EXPECT_CALL(sock, Socket(AF_INET, SOCK_STREAM, 0))
.Times(1)
.WillOnce(Return(5)); //fake file descriptor
ASSERT_TRUE(net.init(&sock));
}
} // namespace
// gtest boilerplate main() omitted
This is well and good, but I wonder how to make this work if I really needed my pointers. Sounds like an exercise for the reader. ;)
How about:
TEST_F(NetworkTest, InitCallsSocket) {
EXPECT_CALL(*((MockSocket)*socket_ptr), Socket(AF_INET, SOCK_STREAM, 0))
.Times(1)
.WillOnce(Return(5)); //fake file descriptor
ASSERT_TRUE(net.init(socket_ptr));
}
(Disclaimer - I did not check if it compiles...)
来源:https://stackoverflow.com/questions/5780747/what-is-wrong-with-my-attempts-to-mock-a-simple-c-method-with-googlemock