Can I get away with not mocking all methods in an interface in C++ when using googlemock - c++

I am using Google Mock 1.6 RC and am trying to Mock a COM Interface. There are close to 50 methods in the COM Interface some of which are inherited from base interfaces. When I create a mock struct that inherits from this interface and mock only the methods I am using, I get the cannot instantiate abstract class error.
I want to know if it is possible to do this in googlemock or not.

It is not possible to do. You have to overload all pure virtual methods from all interfaces (except for the constructor and destructor).

You have to override every method that has been declared as pure virtual in the classes you inherit from, directly or indirectly. There are two reasons not to want override them all:
There are too many of them and you have something better to do with your time than to go over them all.
Compiling a mock class with all of them mocked out is too slow and takes too much memory.
The fix for (1) is to use the gmock_gen.py script in Google Mock's scripts directory. It goes over the class definition and converts method declarations into the MOCK_METHOD statements. If you have problems with (2), you can replace the unnecessary MOCK_METHOD statements with stubs:
MOCK_METHOD1(f, bool(int i));
with
virtual bool f(int i) {
thrown std::exception("The stub for f(int) has been invoked unexpectedly.");
}
Throwing an exception will alert you to a situation where a particular stub has been invoked, meaning you likely need to mock it instead.
Edit: If the original interfaces to mock are written using Microsoft's macros, this thread has a script posted that converts them to C++ acceptable to gmock_gen.py.

I'm not entirely sure whether all methods should be covered in the mock class... In the gmock examples you can see that for example destructors are not mocked. Therefore I presume there is no need to mock the entire class.
Anyway, shouldn't you create mock class rather than mock struct?
However, there is a gmock_gen.py tool in scripts/generator that should do the hard work of mocking large classes for you.

Related

HippoMocks: is it possible to mock non-virtual methods?

I've starting using HippoMocks for writing unit tests. I would like to know if it's possible to mock non-virtual class methods?
A first look at the code seems to indicate that the framework only supports virtual methods. But as it supports the mocking of simple C functions, it should be possible to do the same for non-virtual class methods.
Is there a way to achieve that?
It's not impossible, but it would lead to very weird use mechanisms - or no possibility for thread-safety.
C functions are flat-out always mocked. In that case it's always redirecting to the mock, you cannot call the original anymore.
C++ virtual functions are only mocked for the requested object, and any other object will still have the regular function there.
C++ non-virtual functions would look like a virtual function, but only be mockable on a per-class level. It's also very likely that your compiler will inline these functions, making it not likely to be reliable.
I've had a patch from somebody that just applied it blindly, and it suffered from the described problems. You'd need to be 100% sure that any access to that member function is not inlined, which is just about impossible.

Static Methods As A Wrapper

If you have a class called MyClass with a set of public methods; MethodA, MethodB and MethodC. And in some locations of an application you only need a single method from MyClass, for example:
MyClass myClass = new MyClass();
myClass.MethodA();
To simplify the above I would like to create a single static method that wraps the above lines of coded. I am planning to write unit tests against MethodA. In my unit test MethodA interacts with an interface that is implemented using a mock framework (I think this is called Inversion of Control).
Is it safe to assume that by testing MethodA that the static method (wrapper method) is also being tested indirectly. I am assuming the actually implementation for the interface used in MethodA is also being tested.
Or should I not implemented the static method?
Please, don't do that!
Static methods used like you want to do are the exact opposite of inversion of control / dependency injection, and as such, are a bad practice.
What you want to do is inject into all classes that need a MyClass an interface to it (either injected through the constructor or a setter, manually or using a IoC framework like Spring).
If you wrap your lines of code in a static method that you call from another class, then you'll couple the specific implementation of MyClass too tightly, which is the opposite of what you want to achieve.
But to answer your more specific question, it's never safe to assume the code is tested by another test, unless it actually is. What I mean is: if there is NO test that go through the static method, then it's not covered. Even if you may think it's trivial, don't forget it may be refactored later, and no test will indicate it's broken.
No, it's not safe to assume the wrapper method is also being tested. There is code in the wrapper method, and that code could have a defect in it, so you'll need to write unit tests against that code as well.

How do you create a mock object without an interface class in AMOP?

I'm just getting into Test Driven Development with mock objects. I can do it the long way with UnitTest++, but now I want to try to minimize typing, and I'm trying to use AMOP mock framework to do the mocking.
AMOP states:
The main differences between AMOP and other mock object library is that,
users DO NOT need to implement the
interface of the object which to
mock...
However, I can't figure this out. The basic usage page still shows a IInterface class. Anyone able to do it without using an interface class?
For what I've seen in the documentation, it actually doesn't need the mock object to implement any interface. The mocking object is constructed based on the original object's interface, but not by inheritance, but as a parameter of the class:
TMockObject<IInterface> mock;
No inheritance here, and TMockObject doesn't get tied to any interface by inheritance. Then, adding mock methods to be implemented by the mock object:
mock.Method(&IInterface::SimpleFunction);
mock.Method(&IInterface::SimpleFunctionWithAlotParams);
((IInterface*)mock)->SimpleFunction();
((IInterface*)mock)->SimpleFunctionWithAlotParams(0, 0, 0, 0, std::string());
Again, the object mock does not actually inherit the interface. It may redefine the conversion operator to IInterface* (it will return an internal IInterface object).
I don't see many advantages in not inheriting the interface, but anyway. I would have preferred some template as member function of TMockObject to give more meaning to that ugly cast (not tested, just an idea):
template <typename I>
I* as(void)
{
return m.internal_interface_pointer_;
}
so you could write something like:
mock.as<IInterface>()->SimpleFunction();
but still...
This is the first time I hear that a mock framework doesn't need an interface to crate mock objects. Every other do. Must be a bug in the documentation.

Mocking non-virtual methods in C++ without editing production code?

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.

For me to use Moq, do all my classes have to implement an interface?

I want to use Moq, but I am using Nhibernate and I didn't create interfaces for all my Model classes (POCO classes).
Do I have to create an interface for each class for me to be able to moq my POCO classes?
You can mock virtual methods, but its best if you use an interface.
Reason I say this is as follows:
var mockObject = new Mock<IMyObject>();
If you use a virtual method it becomes:
var mockObject = new Mock<MyObject>(params...);
You are forced to include the parameters for concrete objects, but you obviously don't need to for interfaces. All tests using concrete classes will require updating if you decide to change the class' constructor at a later date. I've been burned by this in a past so try not to use virtual methods for testing anymore.
I should add that by attempting to mock concrete types you are defeating the purpose of mocking frameworks. You should be mocking roles, not types. Therefore working to an abstraction, in this case an interface is a great thing to do.
Another reason is how interfaces work, interfaces state a contract but not behavior. They should be used when you have multiple implementations, and I class testing as a behavior hence the valid reason to introduce a new interface.
The classes/methods you are Mocking either need to implement an interface or be virtual. You can test any class/method as long as its accessible, but there's no way to mock something that cannot be overridden or implemented explicitly.