I need to write simple http client. It could be great to have unit tests for my class. But I don't know how to write proper and testable class.
For example, I have a client like this:
class HTTPClient
{
public:
HTTPCLient(const std::string& host, const std::string& port): session(host, port) {}
void send()
{
session.sendRequest(someRequest);
Response response = session.receiveResponse();
// ...
}
private:
SomeLibrary::ClientSession session;
};
How to test send
method (that I really send what I want)? I can't mock it. I can write that HTTPClient
receives SomeLibrary::ClientSession
object in constructor (in test I would pass mock) but is it good design? I think that the way of implementing of session etc. should by hidden in my class.
Do You have any idea?
Best Answer
Yes, it would be a good design to break that direct dependency on the session implementation and instead inject it. (Not only for testing purpose.)
Note the use of
auto
for the response type. Alternatively, require that aSessionT
provides an appropriate nestedtypedef
.If you don't want to use
template
s, you would have to define avirtual
interface for your sessionclass
and use it through smart pointers. I recommend to stay with thetemplate
.Note that this generalization has purpose beyond unit testing. For example, you might want to try a different library, use HTTPS with different TLS implementations, connect to a local server via UNIX domain sockets, communicate with a server process via a pair of pipes, or even implement client and server in the same process, communicating via a message queue. Not all of these options may sound relevant to you today but it is good to have the flexibility.
By the way, shouldn't your “session” actually be a “connection”?