I like the things that templates methods can do for me, since they can be used to dramatically simplify some code I'd otherwise have to write over and over.
However, I have a very hard time testing any classes that depend on collaborators that have public template methods. The real problem is they can't be virtual, so my usual method of subclassing dependencies and stubbing doesn't work.
Presently, my solution is to create a non-templated interface that includes every type that's supported, then use the templates as an implementation detail. This is testable, but is tedious to update for large numbers of types passing through many classes. I suppose I could also redesign to use inheritance-based polymorphism instead, but if my problems with testing could be solved without a system redesign I'd prefer that.
I thought there might be something I could do with using template specialization to change the behaviour in my test library vs. my production library, but I'm not sure if that's effective... or even possible.
So, what's the best way of testing classes that use templated methods in their dependencies?
Google mock framework provides a way to create a mock with template parameters. Then you have to add a templated base class and pass a mock object to the constructor of the class under test.
I wanted to investigate this further, so I took some time to try out the template specialization solution I was thinking of. It's possible to do this, but still a real pain. The big restriction on template specialization is that it must be done before any reference is made to the template. Basically, this means you have to do your mocking for any types used in tests in the same header file as the production code. That's bad enough for simple types, but could be tricky or impossible for classes in other libraries, due to the need to have the type defined where it's specialized.
Therefore, I don't think template specialization is a feasible way to mock out a function for unit tests. Making the class under test a template and using Google mock to generate the mock version seems to be the only reasonable solution short of defining a non-template interface.
Related
I have a complex mock class that can expose other (necessary) mock instances just by reference. Since there are circular dependencies I have to solve these, using forward declarations and put implementations to concrete compilation units (to see the completed class declarations).
When writing testcases, I want to behave these instances like testing::NiceMock<T>, but I can't see a direction how to achieve this.
Replacing the exposed references with testing::NiceMock<ExposedMockClass>* or testing::NiceMock<ExposedMockClass>& doesn't work since ExposedMockClass is just forward declared at that point.
Is there a technique available with gmock on board utilities to achieve this?
NiceMock<T> inherits from T, so the only thing that needs to know it's a NiceMock is the thing that creates it. From that point onwards, you can deal with it as T.
For example, it's perfectly ok to do this:
ExposedMockClass* mockObject = new testing::NiceMock<ExposedMockClass>();
EXPECT_CALL(*mockObject, exampleFunction(_,_));
Why would you have an abstract base class defining an interface for a library where there is only one (always and forever) derived class?
You may want to swap out the implementation for something like Unit Testing
One reason why you would do this is for testability. It is much simpler to test dependent objects when their dependencies are defined as interfaces. This give the easy ability to mock or stub.
To violate the reused abstraction principle.
In short, don't do this.
Those who say "for testing" are overlooking that you can just replace
Base < - > Derived
Base < - > DerivedForMockingAndTesting
with
Derived < - > DerivedForMockingAndTesting
That is, let your existing implementation Derived serve as the "abstraction" to be mocked out and tested in unit testing.
If you can be 100% certain that there will always be only one and exactly one derived class? Not much reason. BUT: In reality you hardly will be 100% certain of anything and surely not the future of your code.
You may find the need for different versions of that class to be binary compatible. You may also find that for other reasons, you wish to encapsulate the definition of the class- for example, because the definition requires a header which has poor macros, and that kind of thing, or the header containing what's necessary to define the class has a very long compile time.
For example, I wrote a class to encapsulate the features offered by my operating system- for now, things like dynamic loading and creating a window. Even though there'll only ever be one implementation for one compile target (Windows, etc), I chose to use a run-time abstraction, because I wanted to guarantee that the rest of my code never saw a platform-specific header, and the Windows header is full of so many macros and stuff, that I didn't want them leaking out.
The most obvious reason would be to be able to put the class'
implementation in a source file, and not in a header. All that is
exposed in the header is the abstract base class (and a factory function
necessary to construct it, but this could be a static member). This
avoids having to include the header files for any member data; the pimpl
idiom is more idiomatic in C++ for this, but using abstract classes like
this is far from unknown, and works fairly well as well.
I am a fairly new software developer currently working adding unit tests to an existing C++ project that started years ago. Due to a non-technical reason, I'm not allowed to modify any existing code. The base class of all my modules has a bunch of methods for Setting/Getting data and communicating with other modules.
Since I just want to unit testing each individual module, I want to be able to use canned values for all my inter-module communication methods. I.e. for a method Ping() which checks if another module is active, I want to have it return true or false based on what kind of test I'm doing. I've been looking into Google Test and Google Mock, and it does support mocking non-virtual methods. However the approach described (https://google.github.io/googletest/gmock_cook_book.html#MockingNonVirtualMethods) requires me to "templatize" the original methods to take in either real or mock objects. I can't go and templatize my methods in the base class due to the requirement mentioned earlier, so I need some other way of mocking these virtual methods
Basically, the methods I want to mock are in some base class, the modules I want to unit test and create mocks of are derived classes of that base class. There are intermediate modules in between my base Module class and the modules that I want to test.
I would appreciate any advise!
Thanks,
JW
EDIT: A more concrete examples
My base class is lets say rootModule, the module I want to test is leafModule. There is an intermediate module which inherits from rootModule, leafModule inherits from this intermediate module.
In my leafModule, I want to test the doStuff() method, which calls the non virtual GetStatus(moduleName) defined in the rootModule class. I need to somehow make GetStatus() to return a chosen canned value. Mocking is new to me, so is using mock objects even the right approach?
There are some different ways of replacing non-virtual functions. One is to re-declare them and compile a new test executable for each different set of non-virtual functions you'd like to test. That's hardly scaleable.
A second option is to make them virtual for test. Most compilers allow you to define something on the command-line so compile your code with -DTEST_VIRTUAL=virtual or -DTEST_VIRTUAL to make them either virtual or normal depending on whether or not it's under test or not.
A third option which may be usable is to use a mocking framework that lets you mock non-virtual functions. I'm the author of HippoMocks (disclaimer with regard to neutrality and so on) and we've recently added the ability to mock plain C functions on X86 platforms. This can be extended to non-virtual member functions with a bit of work and would be what you're looking for. Keep in mind that, if your compiler can see both the use and the definition of a function at one time that it may inline it and that the mocking may fail. That holds in particular for functions that are defined in headers.
If regular C function mocking is sufficient for you, you can use it as it is now.
I would write a Perl/Ruby/Python script to read in the original source tree and write out a mocked source tree in a different directory. You don't have to fully parse C++ in order to replace a function definition.
One approach would be to specify different sources for testing. Say your production target uses rootModule.h and rootModule.cpp. Use different sources for your testing target. You can specify a different header by changing your include path, so that #include "rootModule.h" actually loads unittest/rootModule.h. Then mock rootModule to your heart's content.
Should you design your code to make testing easier? And if so how to design c++ code so that it is easy to test.
How do you apply dependency-injection in c++?
Should I implement the classes using a pure interface class as the base in order to simplify the creation of fake test objects?
That would force me into making a lot of virtual methods. Will that affect performance?
What else should I think about when designing for testability in c++?
Should I implement the classes using a pure interface class as the base in order to simplify the creation of fake test objects?
That would force me into making a lot of virtual methods. Will that affect performance?
A workaround I often use is to templatize the class instead of hiding it behind an interface. Then I can pass test/mock objects as template parameters when testing, and the real objects otherwise. That way, the performance hit of virtual functions is avoided.
Edit
Ok, a simple example:
With OOP and interfaces, you might write a function such as this:
void Foo(IBar& someBar) { ... }
This function takes a parameter which implements the IBar interface, and does something with it. If you want to pass in a dummy mock implementation, you simply write a mock object which inherits from IBar and pass that to Foo. Simple and straightforward.
But you can achieve the same thing with templates:
template <typename BarType>
void Foo(BarType& someBar) { ... }
... and that's it. The body of Foo can be pretty much unchanged. As long as the type passed to the function exposes all the members we need, it'll work, without having to formally inherit from an interface class, and without the overhead of virtual functions and runtime polymorphism.
Don't design too much up from the start, then write a test, then make it pass, but not more than that. Keep your functions very short. Look what you've done and refactor it. If you're going to write a comment, better put the code in question to a separate function with a good name.
And don't spend too much time thinking of patterns, that's a lot of science and little outcome, just write a test first and keep your code simple, then, surprisingly you don't need to write tests for it, you've done it already. And your code works.
Maximum cohesion and minimum coupling.
This will make your life easier with testing.
I think prime concern should be ...
Achieving Functionalities
Code Extensiblity
Code Resuablity
Code Maintainability
To be able to unit test my C++ code I usually pass the constructor of the class under test one or several objects that can be either "production code" or fake/mock objects (let's call these injection objects). I have done this either by
Creating an interface that both the "production code" class and the fake/mock class inherits.
Making the class under test a template class that takes the types of the injection objects as template parameters, and instances of the injection objects as parameters to the constructor.
Some random thoughts:
Until we have concepts (C++0x), only documentation and parameter naming will hint what to provide the class under test (when using templates).
It is not always possible to create interfaces for legacy code
The interface is basically only created to be able to do dependency injection
In the same way: templating the class under test is done only to enable dependency injection
What are your thoughts? Are there other solutions to this problem?
With C++, there's another option - you give your mock classes exact same names as the real classes, and when linking your unit tests, just link them with mock object/library files instead of real ones.
I think interface option is better, but one doesn't have to create common base class just for test. You can inherit your mock class from production class and override necessary methods. You'll have to make the methods virtual though, but that's how tools like mockpp work and they also allow automate this process a little bit.
Templates will have slightly less performance penalties for runtime (less indirections, less calls, more inline optimizations), but will make you suffer a very high penalty for compilation times...
I think that for this purpose, interfaces are better (until we have concepts in C++0x TR1)... unless if you can't slow down some "bottleneck code". Interfaces are more dynamic and switchable at run-time.
Remember that you can construct your class with default injection objects (the real ones), but you can have factories that inject the mock ones on your tests... you don't even need to subclass.
Don't know if it helps, but you can have template constructors:
struct Class_Under_Test
{
template <typename Injected>
Class_Under_Test()
{
...
// and even specialize them
template <>
Class_Under_Test <A_Specific_Injection_Class>
{
...
Only the one that is actually used will get included.