Mocking a function call inside a constructor - c++

I have built a file manager(basically reads/writes) class I am trying to unit test. The file format basically belongs to a third party for which I have third party function calls in the constructor. I call all third party calls through wrapper methods
My question is this: Before starting to unit test any method in the class I am trying to instantiate the constructor which looks something like this:
Filemanager::Filemanager{
if(wrapperfoo()){
file->open() //for writing
}
initialise();
}
Now I have a mock class MockManager to mock Filemanager. When I am trying to instantiate MockManager,
I need to mock wrapperoo to return true. However, since the manager itself is not instantiated yet, the EXPECT_CALL fails. Since the EXPECT_CALL has to be placed before the new MockManager()
MockManager *mgr;
EXPECT_CALL(*mgr, wrapperfoo()).Return(true) // Crashes here.. Obviously!!
mgr = new MockManager();
How can I handle this case?

I see no chance for this to work, you are forced to build yourself a workaround. You already gave the explanation yourself.
In principle, mocking isn't designed for what you want to achieve, it is designed for testing components in their behavior to an API or interface, where you mock the interface (API) for the component and not vice versa (https://www.youtube.com/watch?v=dLB2aDasVTg&list=PL_dsdStdDXbo-zApdWB5XiF2aWpsqzV55&index=4, very good explanation). In this example you wouldn't use mocking for internal calls (from the contructor), rather in the test case of another component that requests to get the return type from wrapperfoo().

Related

EXPECT_CALL without mock in Google Test

Is there any way to test a function call via GoogleTest for c++ without creating mock object, e.g. we have the following production code:
if (a)
method(x);
I would like to test whether the method will be called in the case a is True and a is False. I would like to construct a test that does exactly the same what Google Test's EXPECT_CALL does, but EXPECT_CALL works only with the mock object's method. In my case I would prefer not to use a mock (there is no need to create any object).
As state here,
It's possible to use Google Mock to mock a free function (i.e. a C-style function or a static method). You just need to rewrite your code to use an interface (abstract class).
Their "It's possible" is misleading, as you have to rewrite code to use class (abstract, or provided by template), and so no longer use free functions.
If you are trying to fake a free function, you may want to look into the Fake Function Framework (fff). It allows you to replace free functions with fake implementations that can be used in a similar way to GoogleMock.
It works seamlessly with GoogleMock and GoogleTest.

Mocking a file write process in googlemock

I am just starting with mocking using googlemock for a C++ project. In my case, my class to be tested observes a file that is written to, and whenever a minimal amount of new data has been written, it starts doing some work.
What I need is a mock class for the process writing to the file. As far as I understand things, I need to completely implement this "writing to file" functionality in form of (for googlemock) a virtual class from which a mock class is derived? The mock wrapper is finally used for testing and evaluation purposes, right?
Thanks for help!
Mocks, in google mock terms, are objects used to validate that your code under test performs certain operations on them.
What you describe is not a mock, but a utility class that triggers your code under test operations.
What does your class do when it detects that the file it observes is written to? If, for instance, it performs a call to another object, then you could use a mock object to check that it gets called with the right parameters, e.g. the new bulk of data written to the file.
I am assuming that an object of your "observer" class is notified
that minimal amount of data has been written by an object of
the "writter" class. In that case, you need to implement an abstract
class that represents an interface for your "writter" class, and have
your real "writter" class inherit from it and override its virtual functions.
Also, have your mock "writter" class implementation inherit from this interface and
and create mock implementations using MOCK_METHODn.
Then, have your "observer" class receive notifications from "writter" object
using a pointer to the abstract class. This way, you can use dependency
injection to switch implementation during testing phase by creating a mock
"writter" object and passing its address to "observer" object (instead of an address to a real "writter"
object) and setup test cases using EXPECT_CALL on the mock object.
This is the best advice I can give since you did not provide us with a detailed description of your classes.
EDIT:
Concerning the implementation of your real "writter" class: You do not have to create it immediately, you can use the mock class for now to test the behavior of the "observer" class and leave the implementation for later. You will, of course, have to implement it eventually since it has to be used in production code.

Not Call dependency in Mockito

I have below code, just putting one scenario here.
class A{
public JSONObject m1(type1,type2,type3){
callmethod2(type3);
}
public Map callmethod2(type3){
//some jobs
return myMap;
}
}
#Test
assertequals(JSONObjectTest,m1(type1,type2,type3))
In my test, I am creating a mock with dummy data and passing them to actual function type1,type2,type3 Now there is callmethod2(type3) as a dependency so i do not want to execute that method. so in my test case i written
when(mockA.callmethod2(any(type3.class))).thenReturn(mockMap);
But i can see my callmethod2 is getting execute, how can i solve this and set some expected result for that method in my test case, so it will not execute.
Your code scenario at the time I am writing this is a little incomplete, but I will try to read between the lines. I assume you are somewhere creating a mock instance of class A. I am also assuming you are using that mocked instance to invoke the instance method "m1".
If either of these things are not true, then you will have problems. If you do not create a mock instance, then the "when(...)" clause will not function properly, and in fact while you are invoking the "when" clause you will also actually be invoking the real (i.e., unmocked) instance of A.m1(). The same will be true if you properly mock A but then don't use the mocked instance in the "when" clause, or if you don't use the mocked version in your execute/assert statement(s).
But the bigger problem is that if you actually ARE properly creating and using a mock of A, then even the default mocked functionality of method "m1" becomes empty -- do nothing. It would never get executed. The only way to do what you seem to be proposing is to use what Mockito calls "partial mocking", using a Spy. You instantiate a real instance of A, then wrap it in a Spy to make a "Spied"-instance of A. Now the Spied instance of A inherits all of the default implementations of methods, and you can mock out specific methods if you like. You then must use the spied instance in both yur "whe(...)" clauses as well as your execute/assert statements.
But even that endeavor is questionable. You should try to test classes as a whole rather than mocking out partial behavior. In general (practically a rule),you should either mock nor spy the class under test. If you see a need to do so then there is probably a coherency problem with your class, and it is pointing to design issues or a misunderstanding of good testing practices.

Mocking vs. Spying in mocking frameworks

In mocking frameworks, you can mock an object or spy on it. What's the difference between the two and when would/should I use one over the other?
Looking at Mockito, for example, I see similar things being done using spies and mocks, but I am unsure as to the distinction between the two.
Mock object replace mocked class entirely, returning recorded or default values. You can create mock out of "thin air". This is what is mostly used during unit testing.
When spying, you take an existing object and "replace" only some methods. This is useful when you have a huge class and only want to mock certain methods (partial mocking). Let me quote Mockito documentation:
You can create spies of real objects. When you use the spy then the real methods are called (unless a method was stubbed).
Real spies should be used carefully and occasionally, for example when dealing with legacy code.
When in doubt, use mocks.
I'll try to explain using an example here:
// Difference between mocking, stubbing and spying
#Test
public void differenceBetweenMockingSpyingAndStubbing() {
List list = new ArrayList();
list.add("abc");
assertEquals(1, list.size());
List mockedList = spy(list);
when(mockedList.size()).thenReturn(10);
assertEquals(10, mockedList.size());
}
Here, we had initial real object list, in which we added one element and expected size to be one.
We spy real object meaning that we can instruct which method to be stubbed. So we declared that we stubbed method - size() on spy object which will return 10, no matter what is actual size.
In a nutshell, you will spy real object and stub some of the methods.
Mockito warns that partial mocking isn't a good practice and you should revise your Object Oriented architecture. Spy (or partial mocking) is recommended to test legacy code.
Based on Mocks Aren't Stubs by Martin Fowler:
Dummy objects are passed around but never actually used. Usually they are just used to fill parameter lists.
Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production (an in memory database is a good example).
Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what's programmed in for the test.
Spies are stubs that also record some information based on how they were called. One form of this might be an email service that records how many messages it was sent.
Mocks are what we are talking about here: objects pre-programmed with expectations which form a specification of the calls they are expected to receive.
In Mockito if you assign any object to instance variable of Mock Object then does not affect on Mock Object.
But in case of Spy, if you assign any object to instance variable of Spy Object then does affect on Spy Object because of Spy act like real-time object modification.
For a reference example are
#RunWith(MockitoJUnitRunner.class)
public class MockSpyExampleTest {
#Mock
private List<String> mockList;
#Spy
private List<String> spyList = new ArrayList();
#Test
public void testMockList() {
//by default, calling the methods of mock object will do nothing
mockList.add("test");
assertNull(mockList.get(0));
}
#Test
public void testSpyList() {
//spy object will call the real method when not stub
spyList.add("test");
assertEquals("test", spyList.get(0));
}
}
Reference: http://javapointers.com/tutorial/difference-between-spy-and-mock-in-mockito/
When using mock objects, the default behavior of the method when not stub is do nothing. Simple means, if its a void method, then it will do nothing when you call the method or if its a method with a return then it may return null, empty or the default value.
While in spy objects, of course, since it is a real method, when you are not stubbing the method, then it will call the real method behavior. If you want to change and mock the method, then you need to stub it.
Spies have two definitions. One, is where the real method is called, another where, no functionality is called and only null or null equivalent values are returned, but methods were called, and they're state was recorded, commonly like, method x was called y times.
If we want to avoid calling external services and just want to test the logic inside the method then use mock.
If we want to call the external services and use the real dependency i.e to run the program as it is and just stub specific methods then use spy

How do mock frameworks work?

If I was to write a mocking library, how would this work (in other words, how do "they work?)?
One of the things which I wonder is that you are always setting expectations so really you need to compare the expectation to what the method does at runtime, so I assume reflection (resolving types at runtime) is required.
Also, when using the term "mock object", is the object stubbed out or would it be an object with pre-set expectations?
When I think how I would write my own implementation of a framework/technique, like mock objects, I realise how much I really know (or don't know) and what I would trip up on: If the mock object is pre-programmed to return set expectations and you don't call the actual real object, then wouldn't the result always be the same? Eg:
[TestMethod, Isolated]
public void FakeReturnValueByMethodArgs()
{
var fake = Isolate.Fake.Instance<ClassToIsolate>();
// MethodReturnInt will return 10 when called with arguments 3, "abc"
Isolate.WhenCalled(()=> fake.MethodReturnInt(3, " abc")).WithExactArguments().WillReturn(10);
// MethodReturnInt will return 50 when called with arguments 3, "xyz"
Isolate.WhenCalled(()=> fake.MethodReturnInt(3, "xyz")).WithExactArguments().WillReturn(50);
Assert.AreEqual(10, fake.MethodReturnInt(3, "abc"));
Assert.AreEqual(50, fake.MethodReturnInt(3, "xyz"));
}
Wouldn't this always return true?
The idea with mocking frameworks is to mock out dependencies, and not the actual classes under test. For your example, your test will always return true, because really you're only testing the mocking framework and not your actual code!
A real world mock would look more like this:
[TestMethod, Isolated]
public void FakeReturnValueByMethodArgs() {
var fake = Isolate.Fake.Instance<DependencyClass>();
// MethodReturnInt will return 10 when called with arguments 3, "abc"
Isolate.WhenCalled(()=> fake.MethodReturnInt(3, "abc")).WithExactArguments().WillReturn(10);
var testClass = new TestClass(fake);
testClass.RunMethod();
// Verify that the setup methods were execute in RunMethod()
// Not familiar with TypeMock's actual method to do this...
IsolatorExtensions.VerifyInstanceWasCalled(fake);
// Or assert on values
Assert.AreEqual(10, testClass.AProperty);
}
Notice how the mock is passed into the TestClass and a method run on it.
You can read The Purpose of Mocking to get a better idea of how mocking works.
Update: Explanation why you're testing only the mocking framework:
What you've done is create a method MethodReturnInt with the mocking framework using Isolate.WhenCalled(). When you call MethodRecturnInt in the Assert, the code will run the delegate () => fake.MethodReturnInt() and return 10. The mocking framework is effectively creating a method (albeit dynamically) that would look something like this:
public void MethodReturnInt(int value, string value2) {
Assert.Equal(3, value);
Assert.Equal("abc", value2);
return 10;
}
It's a bit more complicated than that, but this is the general idea. Since you never run any code other than the creation of 2 methods and then asserts on those two methods, you're not testing your own code and therefore only testing the mocking framework.
Yes, it will always return true. Mock objects should be used when the class under test requires another class implementation that you don't want to involve in the test run. This is most useful when it's a class that uses interfaces with multiple implementations, or there are complex/expensive/external services that you don't want to set up.
In the above code, you're mocking the class that you're "testing".
Another way of thinking about it is that the mock behaviours you record are black-box (implementation) assertions, where Assert.* are white-box (api) assertions.
You have the right idea. You will often find that they have a couple of modes of operation. If you're worried about your method not getting called or it not getting called in the right order there is quite often a 'strict' mode that causes the mock framework to throw an exception if the method isn't called by the end of the test, or is called with the wrong parameters etc.
Most of the frameworks have thought of those sorts of issues so you just need to find out how to configure it for your scenario.
One way to look at how mock system work is just look at times when you need an object but you don't want to use the real class but instead want it to give you some specific kind of data that it wouldn't (or won't do so reliably). So if you see:
Assert.IsTrue(myLogic.IsNoon(time))
you can see how the assert would want the time object to always be noon. . . well you can't do that with a real object reliably. So you need a stand-in. You can make a fake class just for the test, but that's sort of heavy. Mock frameworks are a shortcut.