I'm writing an RPC middleware in C++. I have a class named RPCClientProxy that contains a socket client inside:
class RPCClientProxy {
...
private:
Socket* pSocket;
...
}
The constructor:
RPCClientProxy::RPCClientProxy(host, port) {
pSocket = new Socket(host, port);
}
As you can see, I don't need to tell the user that I have a socket inside.
Although, to make unit tests for my proxies it would be necessary to create mocks for sockets and pass them to the proxies, and to do so I must use a setter or pass a factory to the sockets in the proxies's constructors.
My question: According to TDD, is it acceptable to do it ONLY because the tests? As you can see, these changes would change the way the library is used by a programmer.
I don't adhere to a certain canon i would say if you think you would benefit from testing through a mock socket the do it, you could implement a parallel constructor
RPCClientProxy::RPCClientProxy(Socket* socket)
{
pSocket = socket
}
Another option would be to implement a host to connect to for testing that you can configure to expect certain messages
What you describe is a perfectly normal situation, and there are established patterns that can help you implement your tests in a way that won't affect your production code.
One way to solve this is to use a Test Specific Subclass where you could add a setter for the socket member and use a mock socket in the case of a test. Of-course you would need to make the variable protected rather than private but that's probably no biggie. For example:
class RPCClientProxy
{
...
protected:
Socket* pSocket;
...
};
class TestableClientProxy : public RPCClientProxy
{
TestableClientProxy(Socket *pSocket)
{
this->pSocket = pSocket;
}
};
void SomeTest()
{
MockSocket *pMockSocket = new MockSocket(); // or however you do this in your world.
TestableClientProxy proxy(pMockSocket);
....
assert pMockSocket->foo;
}
In the end it comes down to the fact that you often (more often than not in C++) have to design your code in such a way as to make it testable and there is nothing wrong with that. If you can avoid these decisions leaking out into the public interfaces that may be better sometimes, but in other cases it can be better to choose, for example, dependency inject through constructor parameters above say, using a singleton to provide access to a specific instance.
Side note: It's probably worth taking a look through the rest of the xunitpatterns.com site: there are a whole load of well established unit-testing patterns to understand and hopefully you can gain from the knowledge of those who have been there before you :)
Your issue is more a problem of design.
If you ever with to implement another behavior for Socket, you're toasted, as it involves rewriting all the code that created sockets.
The usual idea is to use an abstract base class (interface) Socket and then use an Abstract Factory to create the socket you wish depending on the circumstances. The factory itself could be either a Singleton (though I prefer Monoid) or passed down as arguments (according to the tenants of Dependency Injection). Note that the latter means no global variable, which is much better for testing, of course.
So I would advise something along the lines of:
int main(int argc, char* argv[])
{
SocketsFactoryMock sf;
std::string host, port;
// initialize them
std::unique_ptr<Socket> socket = sf.create(host,port);
RPCClientProxy rpc(socket);
}
It has an impact on the client: you no longer hide the fact that you use sockets behind the scenes. On the other hand, it gives control to the client who may wish to develop some custom sockets (to log, to trigger actions, etc..)
So it IS a design change, but it is not caused by TDD itself. TDD just takes advantage of the higher degree of control.
Also note the clear resource ownership expressed by the use of unique_ptr.
As others have pointed out, a factory architecture or a test-specific subclass are both good options in this situation. For completeness, one other possibility is to use a default argument:
RGCClientProxy::RPCClientProxy(Socket *socket = NULL)
{
if(socket == NULL) {
socket = new Socket();
}
//...
}
This is, perhaps somewhere between the factory paradigm (which is ultimately the most flexible, but more painful for the user) and newing up a socket inside your constructor. It has the benefit that existing client code doesn't need to be modified.
Related
I have a class that wraps Asio. It is meant to simulate communication over domain and tcp sockets but I'm at a loss as to automate unit tests. I looked at FakeIt but it only tests virtual methods, GoogleMocks suggests templating my code so I can then pass a MockAsio implementation for unit tests and the real Asio in production.
Are there any other ways to unit test network code? Fake a domain and tcp socket instead of running the whole stack? And if I go with GoogleMock, why use a class that uses GoogleMock and not my own implementation that does whatever I need?
I have recently ran into the same problem. Since an Asio service's methods (socket's read_some for example) are generally not virtual, a simple dependency injection is out of question. As far as I understand, there are two possible approaches, both of them are discussed in the Google Mock Cook Book:
High performance dependency injection (duck typing)
Discussed here.
This is the option #ruipacheco had already mentioned in his question.
This option requires templatizing your class, but it introduces the least code overhead.
If, for example, your class uses an Asio tcp socket, constructing an instance of it would look something like:
asio::io_context io_context;
MyClass<asio::ip::tcp::socket> my_class(io_context);
Code to an interface
Discussed here.
This is more or less what #NiladriBose had suggested.
This option requires writing an Asio interface and an Asio concrete adapter, for every service type (socket, timer, etc...)!
Nevertheless, it's the most generic and robust one (and it does not require templatizing your class, as the previous option did).
If, for example, your class uses an Asio tcp socket, constructing an instance of it would look something like:
asio::io_context io_context;
AsioSocket socket(io_context);
MyClass my_class(socket);
Factory enhancement
If your class uses multiple instances of Asio services (multiple sockets, timers, etc...), it would probably be better to create an abstract Asio services factory.
This factory would receive an io_context in its constructor, and export make_socket, make_timer, etc... methods.
Then, constructing an instance of your class would look something like:
AsioFactory asio_factory(io_context);
MyClass my_class(asio_factory);
Finally, in regard to:
And if I go with GoogleMock, why use a class that uses GoogleMock and not my own implementation that does whatever I need?
See this to understand the difference between mock and fake objects. Generally speaking, I think that mock objects require much less effort.
Also see this to figure out how to incorporate a Google mock class with a fake class.
I am assuming you want to mock out the ASIO wrapper class which is used by your application. If my assumption is correct then say the wrapper has an interface (oversimplified - but most mock frameworks require a pure abstract including gmock)-
class Iasio
{
virtual ~Iasio()
{
}
virtual void send(std::vector<unsigned char> dataToSend) = 0;
virtual std::vector<unsigned char > rcv() = 0;
};
Then you have two options-
1) mock using a mocking framework and in your unit test use the mock ( inject the mock into the classes that are using it using contructor or accessor injection). For this for each unit test scenario you would need to setup the mock object to return your expected data.
2) The first option sometimes can be more cumbersome than writing you own test mock , in such circumstances it is perfectly acceptable to write your own test mock giving you more control. I say more control because mock frameworks are general purpose and they can help in most common scenarios but complex scenarios can demand a bespoke test dummy/mock.
im very curious for peoples opinions on what way a software side application that interfaces with hardware should be unit tested.
For example, the main class of the software application "Connection" would be constructing a handle to a USB device.
I want to test the "Connection" class base function, say "OpenConnection" that would attempt to connect to a USB hardware device.
so far I have constructed a MOCK hardware device, and have included in my connection class a compiler flag, so if its built in unit test mode, it will use a mock object, otherwish it will use the actual hardware interface.
See example below
class TConnection
{
public:
static TConnection* GetConnection();
static void Shutdown();
bool DidInitialise();
bool Write(uint8_t* _pu8_buffer);
bool Read(uint8_t* _pu8_buffer);
protected:
TConnection();
virtual ~TConnection();
bool init();
private:
static TConnection* mp_padConnection;
static bool mb_DidInitialise;
#ifdef _UNIT_TEST_BUILD
static mock_device* mp_handle;
#else
static device* mp_handle;
#endif
};
then in the source file I include something like
#include "connection.h"
#ifdef _UNIT_TEST_BUILD
mock_device* TConnection::mp_handle = nullptr;
#else
device* TConnection::mp_handle = nullptr;
#endif // _UNIT_TEST_BUILD
TConnection::TConnection()
{
...
init();
...
}
bool TConnection::init()
{
mp_handle = hid_open( _VENDOR_ID, _PRODUCT_ID, nullptr );
if (mp_hidHandle == nullptr) {
return false;
}
if (hid_set_nonblocking(mp_hidHandle, _DISABLE_NB) == _ERROR_CODE) {
return false;
}
return true;
}
The only thing I really dislike about my code is that my actual connection class contains test code. I would much prefer them to be separate.
Saying that, I also dont agree with having an entirely new mocked connection class written solely for the purpose of unit testing, it makes me feel like im just writting something designed to work as expected.
So I ask, what would be a better approach to testing such a class
Thank you in advance for your time and advice
You can avoid adding test code to your class by using dependency injection. Create an interface IDevice and make class Device implement that interface. Then, in class TConnection, use pointers to this interface instead of a member of type Device. Also create a helper method that allows you to set a new device, something like:
void setDevice(IDevice *device);
Now, for your production code simple use an instance of class Device, while in your test code use setDevice to swap implementation of device with a mock object. This mock object will be an instance of class MockDevice which will also implement interface IDevice. That way you can change the implementation in tests and use the mock class. Since you are using gtest already, I would suggest you do not write the mock class yourself but use C++ mocking framework gmock (which is fully compatible with gtest) instead. This way, you will also need to create a separate class but almost everything will be handled by the mocking framework. All you need to do is define mocked methods. Creation of an additional interface and mock class seems like overkill at first, but it definitely pays off in the long run. If you want to do any serious test-driving of code, learning to use interfaces, dependency injection and mock classes is essential. Check the documentation for more details:
https://github.com/google/googlemock/blob/master/googlemock/docs/CheatSheet.md
Personally I would have the mock as either a separate class, or part of the test code. To differentiate between mock and actual library I would do the changes in the build script, which I assume would be to include the test file (and mock) or linking to a library.
Creating a separate class is not wasted effort. It should behave as expected, but this can be simplified to the bare minimum needed for the test. A more interesting thing is to make the class generate error events, to make sure your code handles these events correctly. The alternative is sometimes to wait for the error to occur, which I wouldn't recommend.
Two highly recommended books on the subject:
Test-Driven Development for Embedded C: Part 2 gives a good overview of test doubles (mocks being one example) and how to use them.
Modern C++ Programming with Test-Driven Development: Less on test doubles, but more geared towards C++.
I've seen some people creating a "is-a" relationship like the following:
class TCPClient : public Socket
{
public:
TCPClient(const std::string& host, unsigned short port);
};
where the Socket class implements Winsock functions such as Connect(), Close(), Bind() etc.
Examples:
Example 1
Example 2
But this doesn't feel natural to me who is a newbie in socket programming.
Does the above hierarchy make more logical sense than the following "has-a" counterpart?
class TCPClient
{
public:
TCPClient(const std::string& host, unsigned short port);
....
private:
Socket m_socket;
};
A TCPClient uses a socket or has a socket, but is not itself a socket, and you wouldn't normally expect to be able to substitute a TCPClient anywhere a socket was expected. As such, public inheritance doesn't make sense.
You could use private inheritance for this case, but (at least in a typical case) it probably doesn't make much sense either. Private inheritance makes sense primarily when the base class provides at least one virtual function you plan to override in the child class. If you have a virtual function and need to override it, you have no real choice but to use inheritance. I wouldn't expect a Socket class to have an virtual functions though; that wouldn't normally apply here.
That basically leads to your second solution: the TCPClient should contain an instance of a Socket, rather than using inheritance at all.
I should add, however, that the Socket class you've shown seems to conflate the notion of an actual socket with the notion of an address. My first socket class (years ago) worked about like that, but since then I've concluded that it's not really an ideal design. I've become convinced that it's worthwhile to keep the notion of an address separate from the socket itself. Though mine is a bit less elaborate, I find it interesting that what I came up with looks almost like it could have been the prototype from which Boost ASIO was derived. It's a little smaller and simpler, but a lot of the basic ideas are generally pretty similar anyway.
That leads to my next recommendation: take a look at Boost ASIO. Lacking a fairly specific reason to do otherwise, it's what I'd advise (and generally use) in most new code. Although (as I said above) I've written several socket classes over the years, I haven't used any of them in much (any?) new code in quite a while now -- they really only have two possible advantages over ASIO. The first applies only to me: since I wrote and used them before ASIO existed, I already understand them and how they work. The second may be similar: at least to me, they seem a little bit smaller and simpler (but, again, that may be just because I used them first). Even so, the advantages of (for example) using something other people already understand trumps those quite easily.
Use has-a. A TCPClient uses a socket like a person uses a telephone. Would you derive a Person from a Telephone?
class TCPClient : public Socket
{
public:
TCPClient(const std::string& host, unsigned short port);
};
Network sockets are used not only in TCP/IP and the above design is more suitable if you plan to reuse your "Socket" class to implement other protocols using network sockets. For example:
class UDPClient : public Socket
{
};
I would say so. Socket is an abstraction, a file descriptor (UNIX) or handle (Windows), which has resources associated with it and is managed by the operating system. If we consider OSI model, the socket fits well into the presentation layer (it presents, or describes, a communication channel between two nodes), whereas a program that uses the socket sits on the application layer.
Considering this, I would prefer not to inherit from the socket, unless I implement a kind of advanced socket (by analogy: C-pointer vs. smart pointer) to present and handle a logical connection and somehow manage the resources associated with the socket. If XYZClient is an application, whose goal is to implement some business or data processing logic, I would not mix these two concepts together and use the second approach (has-a).
I would split infrastructure/resource-specific and business/application-specific logic.
I'm working on a library that defines a client interface for some service. Under the hood I have to validate the data provided by users and then pass it to "engine" process using Connection class from another library (note: the Connection class isn't known to the users of our library). One of my colleagues proposed using PIMPL:
class Client {
public:
Client();
void sendStuff(const Stuff &stuff) {_pimpl->sendStuff(stuff);}
Stuff getStuff(const StuffId &id) {return _pimpl->getStuff(id);}
private:
ClientImpl *_pimpl;
}
class ClientImpl { // not exported
public:
void sendStuff(const Stuff &stuff);
Stuff getStuff(const StuffId &id);
private:
Connection _connection;
}
However, I find it very hard to test - even if I link my tests to some mocked implementation of Connection, I don't have an easy access to it to set and validate expectations. Am I missing something, or the much cleaner and testable solution is using interface + factory:
class ClientInterface {
public:
void sendStuff(const Stuff &stuff) = 0;
Stuff getStuff(const StuffId &id) = 0;
}
class ClientImplementation : public ClientInterface { // not exported
public:
ClientImplementation(Connection *connection);
// +implementation of ClientInterface
}
class ClientFactory {
static ClientInterface *create();
}
Are there any reasons to go with PIMPL in this situation?
AFAIK the usual reason to use the Pimpl idiom is to reduce compile/link time dependencies to the implementation of the class (by removing the implementation details from the public header file altogether). Another reason may be to enable the class to change its behaviour dynamically (aka the State pattern).
The second does not seem to be the case here, and the first can be achieved with inheritance + a factory as well. However, as you noted, the latter solution is much easier to unit test, so I would prefer this.
GoTW15
GoTW28
From Herb Sutter. Good pointers to get you started.
Yes this is a good place to use the Pimpl pattern, and yes it will be difficult to test as is.
The problem is that the two concepts oppose one another:
Pimpl is about hiding dependencies from the client: this reduces compile/link time and is better from an ABI stability point of view.
Unit Testing is usually about surgical intervention in the dependencies (use of mock ups, for example)
However, it does not mean that you should sacrifice one for another. It merely means that you should adapt your code.
Now, what if Connection was implemented with the same idiom ?
class Connection
{
private:
ConnectionImpl* mImpl;
};
And delivered through a Factory:
// Production code:
Client client = factory.GetClient();
// Test code:
MyTestConnectionImpl impl;
Client client = factory.GetClient(impl);
This way, you can access the nitty gritty details of your test implement of connection while testing client without exposing the implementation to the client or breaking the ABI.
I have probably a quite simple problem but I did not find a proper design decision yet.
Basically, I have 4 different classes and each of those classes has more than 10 methods.
Each of those classes should make use of the same TCP Socket; this object keeps a socket open to the server throughout program execution. My idea was to have the TCP obejct declared as "global" so that all other classes can use it:
classTCP TCPSocket;
class classA
{
private:
public:
classA();
...
};
class classB
{
private:
public:
classB();
...
};
Unfortunately, when declaring it like this my C++ compiler gives me an error message that some initialized data is written in the executable (???). So I am wondering if there is any other way I could declare this TCP object so that it is available for ALL the other classes and its methods?
Many thanks!
I'd suggest you keep the instance in your initialization code and pass it into each of the classes that needs it. That way, it's much easier to substitute a mock implementation for testing.
This sounds like a job for the Singleton design pattern.
The me sounds more for the right time to use Dependency Injection as i tend to avoid Singleton as much as i can (Singleton are just another way for accessing GLOBLAS, and its something to be avoided)
Singleton vs Dependency Injection has been already discussed on SO, check the "dependency injection" tag (sorry for not posting some links, but SO doens't allow me to post more than one link being a new user)
Wikipedia: Dependency Injection
As per your current code example, should be modified to allow injecting the Socket on the constructor of each Class:
class classA
{
private:
public:
classA(TCPSocket socket);
...
};
class classB
{
private:
public:
classB(TCPSocket socket);
...
};
Pass the socket into the constructor of each object. Then create a separate factory class which creates them and passes in the appropriate socket. All code uses the set of objects which are required to have the same socket should then create them via an instance of this factory object. This decouples the classes that should be using the single socket while still allowing the enforcement of the shared socket rule.
The best way to go about doing this is with a Singleton. Here is it's implementation in Java
Singleton Class:
public class SingletonTCPSocket {
private SingletonTCPSocket() {
// Private Constructor
}
private static class SingletonTCPSocketHolder {
private static final SingletonTCPSocket INSTANCE = new SingletonTCPSocket ();
}
public static SingletonTCPSocket getInstance() {
return SingletonTCPSocket.INSTANCE;
}
// Your Socket Specific Code Here
private TCPSocket mySocket;
public void OpenSocket();
}
The class that needs the socket:
public class ClassA {
public ClassA {
SingletonTCPSocket.getInstance().OpenSocket();
}
}
When you have an object which is unique in your program and used in a lot of places, you have several options:
pass a reference to the object everywhere
use a global more or less well hidden (singleton, mono-state, ...)
Each approach have its drawbacks. They are quite well commented and some have very strong opinions on those issues (do a search for "singleton anti-pattern"). I'll just give some of those, and not try to be complete.
passing a reference along is tedious and clutter the code; so you end up by keeping these references in some long lived object as well to reduce the number of parameters. When the time comes where the "unique" object is no more unique, you are ready? No: you have several paths to the unique object and you'll see that they now refer to different objects, and that they are used inconsistently. Debugging this can be a nightmare worse than modifying the code from a global approach to a passed along approach, and worse had not be planned in the schedules as the code was ready.
global like approach problem are even more well known. They introduce hidden dependencies (so reusing components is more difficult), unexpected side-effect (getting the right behaviour is more difficult, fixing a bug somewhere triggers a bug in another components), testing is more complicated, ...
In your case, having a socket is not something intrinsically unique. The possibility of having to use another one in your program or to reuse the components somewhere were that socket is no more unique seems quite high. I'd not go for a global approach but a parametrized one. Note that if your socket is intrinsically unique -- says it is for over the network logging -- you'd better encapsulate it in a object designed for that purpose. Logging for instance. And then it could make sense to use a global like feature.
As everyone has mentioned, globals are bad etc.
But to actually address the compile error that you have, I'm pretty sure it's because you're defining the global in a header file, which is being included in multiple files. What you want is this:
something.h
extern classTCP TCPSocket; //global is DECLARED here
class classA
{
private:
public:
classA();
...
};
something.cpp
classTCP TCPSocket; //global is DEFINED here