C++ Mocking Tips and Tricks for Easier Unit Testing – Part Two

In the first part, we showed you seven examples (out of thirteen) that can make your unit testing painless. Such as how to count the number of times a specific method was called, to check if the constructor initializes the lastname field as it should and more!

In this second part, we’ll continue and add six more tips and tricks for easier unit testing.

In order to do that you need to use a good mocking solution to help you unit tests. You can download our mocking solution HERE.

1) CallOriginal Macro:
In the next example, we execute the original logic of the method “GetZipCode” on the faked object(“fakeAdress”).

First, we initialize an object of type Person and a pointer to an object of type Address that we fake(“fakeAdress”).
The “GetZipCode” method belongs to ‘class Address’ and is called inside the “GetAddressZipCode” method that belongs to ‘class Person’.
The “GetZipCode” methods return -1 when is called.

Next, we use the WHEN_CALLED macro from our API, which receives the call to the method (“GetZipCode”) from the faked object (“fakeAdress”) and then we use the ‘CallOriginal’ macro from our API so that when the faked object (“fakeAdress”) calls the method “GetZipCode” it will execute the original logic(return -1).

The final step is to assert whether the call to the method(“GetZipCode”) with the faked object(“fakeAdress”) will return -1.

See example:

When should you use the CallOriginal macro?
– When you need to execute the original logic of the method.

2) Ignore Macro:
In the next example, we ignore the method “SetStreetName” whenever it is called.
First, we initialize an object of type Person and an object of type Address.
The “SetStreetName” method belongs to ‘class Address’ and is called inside the “SetStreetNameOnAddress” method that belongs to ‘class Person’.

Next, we use the WHEN_CALLED macro from our API, which receives the call to the method (“SetStreetName”) from the object of type Address (“address”) and then we use the ‘Ignore’ macro from our API so that whenever the “SetStreetName” method is called it will be ignored.

Then, we call the method “SetStreetNameOnAddress” from the object of type Person (“person”) which receives the object “address” and a string(in our case “HighStreet”), with this action the Ignore attribute is being activated and the method “SetStreetName” is being ignored.

The next step is initializing a variable of type string (“result”) with the call of “GetStreetNameFromAddress” from the object “person” which returns the string of “address”.

The final step is to assert whether the call to the method(“SetStreetName”) was ignored, meaning if “result” is an empty string. We use the compare attribute for that.

See example:
When should you use the Ignore macro?
-When you need to ignore all the calls of a specific method(P.S work only on void returning methods).

3) Return Macro:
In the next example, we change the behavior of a method with our Return macro.

First, we initialize a pointer of type Person* (“fake”) and we use the (FakeOptions::CallOriginal) from our API that makes all the methods of class Person call the actual implementation instead of returning “Recursive Fakes” .

The “GetAddressLocation” method returns a pointer to an object of type GPSLocation and belongs to ‘class Person’, the class GPSLocation has a private member called “latitude” and a method called “Latitude” which returns the value of the member(“latitude”).

Next, we use the WHEN_CALLED macro from our API, which receives the call to the method (“Latitude”) through (“GetAddressLocation”) from the faked object (“fake”) and then we use the ‘Return’ macro from our API so that whenever the method above is called it will return the value 10.

The final step is to assert whether the call to the method “GetLocationLatitude” from the faked object (“fake”) will return 10.

See example:

When should you use the Return macro?
-When you want to change a method’s behavior.

4) PRIVATE_ASSERT_WAS_CALLED Macro:
In the next example, we assert whether the private method “SetCountryInternal” was called.

First, we initialize an object of type Person(“person”) and a pointer of type Address* (“pAddress”), then we use the (FakeOptions::CallOriginal) from our API that makes all the methods of class Person call the actual implementation instead of returning “Recursive Fakes” .

In the implantation of the method “SetAddressCountryInternal” there is a call to the method “SetCountryInternal”.

Next, we call via the object person to the method “SetAddressCountryInternal” with the faked object(“pAddress”) and the String we implant in the address value

The final step is to assert whether the call to the method “SetCountryInternal” was made, we use our PRIVATE_ASSERT_WAS_CALLED macro from our API which receives the faked object(“pAddress”) and the method we want to assert if called.

See example:

When should you use the PRIVATE_ASSERT_WAS_CALLED macro?
-When you want to assert whether a private method is called.

5) PRIVATE_WHEN_CALLED +Return Macros:
In the next example, we change the behavior of a private method with our PRIVATE_WHEN_CALLED and Return macro combine.

First, we initialize a pointer of type Person* (“person”).

The “Ping” method belongs to ‘class Person’ and in the method implantation we call the private method “CanPing”.

Next, we use the PRIVATE_WHEN_CALLED macro from our API, which receives the calling object (“person”), the private method(“CanPing”) and the type of the method(in our case bool). We use the Return macro from our API to change the behavior of the private method so when “CanPing” is being called the method will return true every time.

The final step is to assert whether the call to the method “CanPing” will return true.

See example:

When should you use the PRIVATE_WHEN_CALLED macro?
-When you want to change a private method’s behavior.

6) ISOLATOR_INVOKE_FUNCTION macro:
In the next example, we are invoking the private static method “IsGpsFound”.

First, we initialize a variable of type bool (“res”) and we assign false to him.

Then, we use the ISOLATOR_INOVKE_FUNCTION macro from our API which receives the variable “res”, the private static method “IsGpsFound” and the parameters the method is receiving(in our case 2 integers 10 and 10), as you can see there is an underscore between “res” and “IsGpsFound”, this space is for a related instance(no need in our case).

The “IsGpsFound” method receives 2 integers and checks if both of them are positive, if so it returns true, otherwise return false.

The final step is to assert whether the returned value from the call to the method “IsGpsFound” equals true.
See example:

When should you use the ISOLATOR_INOVKE_FUNCTION macros?
-you should use them is this case: when you want to invoke a private method without accessing with a member.

Have other cases you want us to write about? Feel free to share with us in the comments.
Need implementing those tips and tricks? Feel free to reach our support team at support@typemock.com