GMOCK - mock an object and its inside mock method - c++

I am writing a GMOCK test cases for a class:
class A{ .. void Text() .. };
Now one of the member method of class A has an class B type object embedded into it and also refers to static member methods:
void A::Text()
{
B bobj;
B::SMethod();
bobj->BMethod();
......
}
In such a case how can I mock B and its methods?

Instead of testing A, you can test a class derived from it, let's call it TestableA. In A make Text() virtual and in override use mock of the B. Also, have a look at this question for more ideas of how to mock classes with static methods.
Nevertheless, the best solution would be to break existing tight dependency between A and B by introducing an interface (e.g. InterfaceB) and injecting it into Text(). SMethod() would become a (non-static) member of the interface. In production you'd be injecting ActualB where ActualB::SMethod() calls static B::SMethod(). In tests you'd use MockB::SMethod(), tailored by test needs.

Related

ABAP Unit Testing - local test class testing a code of other global class

is there a clean way to write a unit test of a productive code (especially the private methods) of global class CL_A from local test class LCL_B which is under the global test class TC_B? So far I have figured out a trick, which is far from clean coding practice. TC_B is a friend of CL_A and LCL_B is a local friend with TC_B. If I want to test method M_A of class CL_A I have to create extra wrapper method M_B in a global test class TC_B which calls M_A. See a pseudo code sample lower as this could be confusing without structured example.
Thanx!
CLASS CL_A definition global friends TC_B.
private:
METHODS: M_A.
CLASS TC_B definition for testing.
private:
METHODS: M_B
IMPORTING cut TYPE REF TO CL_A.
METHOD M_B.
cut->M_A().
ENDMETHOD.
CLASS LCL_B definition deferred.
CLASS TC_B definition local friends LCL_B.
CLASS LCL_B definition final for testing.
private:
DATA: cut TYPE REF TO CL_A.
env TYPE REF TO TC_B.
METHODS: test_M_A for testing,
setup.
METHOD setup.
CREATE OBJECTS cut, env.
ENDMETHOD.
METHOD test_M_A.
env->M_B( cut ).
ENDMETHOD.
Test publics, not internals, because of the detailed reasoning given there.
If not possible, for example because you are caught up in legacy code, establish a global test class that is friends with the original class, and that exposes private methods as public methods.
CLASS original_class DEFINITION.
PRIVATE SECTION.
METHODS some_private_method ...
ENDCLASS.
CLASS test_wrapper DEFINITION PUBLIC CREATE PUBLIC.
PUBLIC SECTION.
METHODS public_wrapper_for_private ...
ENDCLASS.
CLASS test_wrapper DEFINITION GLOBAL FRIENDS original_class.
CLASS test_wrapper IMPLEMENTATION.
METHOD public_wrapper_for_private.
result = some_private_method( ).
ENDMETHOD.
ENDCLASS.
You can then create a local unit test class anywhere that tests test_wrapper.
This solution is fragile and inferior however, and should at most be a temporary means until you get the chance to refactor the original class design.

Can I mock objects creation inside tested code with gMock?

I have a code like this one:
void ClassA::Function()
{
ClassB b;
if (b.doSomething())
{
// ...
}
}
And mock for classB:
class ClassBMock: public classB
{
MOCK_METHOD(doSomething, bool(void));
}
Is it possible to test this function, having ClassBMock created instead of ClassB, so I can use EXPECT_CALL and control what doSomething returns?
No, if you instantiate an object of type ClassB in the context of your to-be-tested function, the compiler (and linker) will make sure that you get an object of type ClassB ;)
What you can do to get an instance of your mock class instead, is e.g. by means of a builder, factory function or you simply pass a pointer to the object b as a parameter to Function(). This way you can inject a mock object, when the code is tested.
Luckily we are talking about C++, so there is one further possible way: Provide a different definition of class ClassB in case ClassA::Function() is compiled/linked in the test context.
I.e. you need to have a different "build-tree" when building the test. Here you can refer to the source file of the productive source-tree, that contains the to-be-tested method. But you can include a different header with the mock definition of ClassB instead of the productive one. In case ClassB is defined in some other library, you link a mock version of it.
All this is not specific for GMock.
What GMock can do for you is summarized nicely in this Cookbook. You can see in virtually any case the construction of the mock/fake object is done in the context of the test coding. It then needs to be "injected" in the to-be-tested code in some way as described above.

Mock Methods that are not virtual

I have a class say A like mentioned below :
class A
{
void show()
{}
int data(int x)
{}
.....
};
I need to mock the class - since the member functions are not virtual - can I design my mock class like mentioned below:
class MockA : public A
{
MOCK_METHIOD0(show, void ());
MOCK_METHIOD1(data, int (int));
}
Can I implement this way and is there a chance from MockA to miss out mocking of
any function of class A?
Objects created using MockA will ever anyway land up calling class A actual method implementation?
Generally for this case you do not have the mock inherit from A and instead use a compile time mechanism to select whether to use an implementation class or a mock class. E.g. templating everything that uses A and then instantiating the templates with either A or MockA, to replace the production class with the mock one in the testing setup. Any methods that are not implemented in the mock, but which are called, result in a compile time error. The use of the macros in the mock definition are pretty much the same even though the methods are non-virtual.
The hard part is replacing the class everywhere. Templates, referencing the class name via a macro, or using the same class name and making sure only one is linked are all possibilities.

What should be the strategy for Unit testing a method calling other methods in the same class?

I am writing unit tests for a class that has a method that calls other methods of the same class. This is leading to a lot of scenarios to be tested.
I am of the opinion that I can spy() the behaviour of the method calls so that I am testing only the method under test and not bothered about other methods behaviour. I will cover them through a separate test for each of those methods.
class MyClass{
public void myMethodToBeTested(){
aPrivateMethod();
aPublicMethod();
}
private void aPrivateMethod(){
// doing something
// Has some if else scenarios
}
public void aPublicMethod(){
// doing something
// Has some if else scenarios
}
}
What would be best way to unit test this class?
You should test by calling the external interface of the class i.e. the public methods.
If those methods call private methods in the same class, then those private methods need to be fully covered too - otherwise how would they be tested?
Stubbing or spying only makes sense for calls to resources or classes outside the class under test.
You're trying to test the entire class, not just individual methods.
In my view the aPrivateMethod could go to a separate class as public and also the body of the aPublicMethod could be a different method in that class.
After this refactoring you can inject the new class and call those methods in the corresponding places.
When it comes to testing, you could mock/stub those methods and test the myMethodToBeTested().
First off, I'd change the private method to default / package-level. That way, a unit test occupying the same package can access it but other methods, outside of that package, can't touch it. Not quite the same thing as private scope, but close enough most of the time.
Then, setup a Spy() on MyClass.
In case you're not clear on that term:
A Mock() on a class will always return null or 0 to any method call
A Stub() on a class lets you define what certain methods in that class should do, but anything you DON'T explicitly specify always returns a null or 0
A Spy() lets you create an object of a class, with all methods in place EXCEPT you can override some of those methods
So create a Spy(MyClass), specify what aPrivateMethod() and aPublicMethod() should return for testing purposes then call myMethodToBeTested() and see what is returned. In your example, that method is void, so it doesn't return anything. But you can always:
define a variable outside of the Spy()
have aPublicMethod() set / modify the variable based on inputs or internal state (your overriding methods in your Spy() can take parameters)
call myMethodToBeTested()
check the contents of that variable

How do you mock classes that use RAII in c++

Here's my issue, I'd like to mock a class that creates a thread at initialization and closes it at destruction. There's no reason for my mock class to actually create and close threads. But, to mock a class, I have inherit from it. When I create a new instance of my mock class, the base classes constructor is called, creating the thread. When my mock object is destroyed, the base classes destructor is called, attempting to close the thread.
How does one mock an RAII class without having to deal with the actual resource?
You instead make an interface that describes the type, and have both the real class and the mock class inherit from that. So if you had:
class RAIIClass {
public:
RAIIClass(Foo* f);
~RAIIClass();
bool DoOperation();
private:
...
};
You would make an interface like:
class MockableInterface {
public:
MockableInterface(Foo* f);
virtual ~MockableInterface();
virtual bool DoOperation() = 0;
};
And go from there.
First of all, it is not necessarily an unreasonable thing that your classes might be well designed for their use, but poorly designed for testing. Not everything is easy to test.
Presumably you want to use another function or class which makes use of the class which you want to mock (otherwise the solution is trivial). Lets call the former "User" and the latter "Mocked". Here are some possibilities:
Change User to use an abstract version of Mocked (you get to choose what kind of abstraction to use: inheritance, callback, templates, etc....).
Compile a different version of Mocked for your testing code (for example, #def out the RAII code when you compile your tests).
Have Mocked accept a constructor flag to turn off its behavior. I personally would avoid doing this.
Just suck up the cost of allocating the resource.
Skip the test.
The last two may be your only recourse if you can not modify User or Mocked. If you can modify User and you believe that designing your code to be testable is important, then you should explore the first option before any of the others. Note that there can be a trade off between making your code generic/flexible and keeping it simple, both of which are admirable qualities.
The pimpl idiom might suit you as well. Create your Thread class, with a concrete implementation that it brings in underneath. If you put in the right #defines and #ifdefs your implementation can change when you enable unit testing, which means that you can switch between a real implementation and a mocked one depending on what you are trying to accomplish.
One technique I've used is to use some form of decorator. Your final code has a method which creates its instance on the stack and then calls the same method, but on a member which is a pointer to your base class. When that call returns, your method returns destroying the instance you created.
At test time, you swap in a mock which doesn't create any threads, but just forwards to the method you want to test.
class Base{
protected:
Base* decorated;
public:
virtual void method(void)=0;
};
class Final: public Base{
void method(void) { Thread athread; decorated->method(); } // I expect Final to do something with athread
};
class TestBase: public Base{
void method(void) { decorated->method(); }
};