I am trying to write unit tests for a socket app. I am using the <sys/socket.h>
header. In order to test a method, I should mock the socket free functions, so the method is tested in isolation from its dependencies. Here is my attempt, following this instructions:
Test file:
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "path/to/ClientConectionHeader"
#include <sys/socket.h>
using ::testing::AtLeast;
class EstablishSocketInterface {
public:
virtual int establishSock(int domain, int type, int protocol) = 0;
};
class EstablishSocket : public EstablishSocketInterface {
public:
int establishSock(int domain, int type, int protocol) override {
return socket(domain, type, protocol);
}
};
class MockSocket : public EstablishSocket {
public:
MOCK_METHOD(int, establishSock, (int domain, int type, int protocol));
};
TEST(ClientConnection, ClientConnectionConstructor) {
MockSocket mockSocket;
EXPECT_CALL(mockSocket, establishSock(AF_INET, SOCK_STREAM, 0))
.Times(AtLeast(1));
std::string serverIp="127.0.0.1";
int port=49151;
ClientConnection client(serverIp,port);
}
Header of the class I am testing:
#pragma once
class ClientConnection
{
public:
ClientConnection(std::string& serverIp_input,int port_input);
private:
int socketfd;
const char* serverIp;
int port;
bool ExitProgram;
};
Constructor definition:
ClientConnection::ClientConnection(std::string& serverIp_input, int port_input) {
this->socketfd=socket(AF_INET, SOCK_STREAM, 0);
if (this->socketfd < 0) {
perror("socket");
}
this->serverIp = serverIp_input.c_str();
this->port = port_input;
this->ExitProgram = false;
}
The test fails with the following: Failure
Actual function call count doesn't match EXPECT_CALL(mockSocket, establishSock(2, SOCK_STREAM, 0))...
Expected: to be called at least once
Actual: never called - unsatisfied and active
[ FAILED ] ClienConection.ClientConectionConstructor (0 ms)
The constructor calls the socket() function itself, does not use the mocked one. Dependency injection can work but requires changing the original code. I don't think this is the right approach. Also, to use EXPECT_EQ()
to check whether the fields are valued the same as the arguments I pass to the constructor, I need getters, which also requires to be added, but are not needed in the 'production' code.
So how do I gtest my methods as I mock the socket()
, send()
, recv()
, close()
functions from the <sys/socket.h>
header?
Thanks in advance!