Answering with Apex Mocks

Sometimes stub a method to return a canned value is not enough.

Sometimes the method you are mocking has some side effect.

Sometimes you need to stub your method with a custom answer.

With Apex Mocks you can bring your stubbing to another level and cover those more complex scenarios, let’s see how.

Let’s say that you are testing n API that calls a method that has a side effect, like this one:

Screen Shot 2017-03-28 at 21.42.23

In our example, the method takes two lists of SObjects and copies the elements in those lists, actually doubling the size of the lists, but it returns only the contacts list.

In our test, to take control of what the doStuff() method return we can stub with a “classic” thenReturn(), or if we need a more complex stubbing use the following:

Screen Shot 2017-03-28 at 22.04.11

what is thenAnswer(new MyAnswer()) doing?

Setting the stubbed value to use a custom Answer.

Unlikely Mockito in Apex we cannot define the answer directly in the stubbing, but we have to define separately the answer and pass an instance to the method.

We can define and shape the answer as we need by implementing the fflib_Answer interface and the related answer() method:

Screen Shot 2017-03-30 at 21.07.02.png

ApexMock would then invoke the callback method “answer()” performing the operations that you have defined.

The fflib_InvocationOnMock instance in the parameter of  the answer method gives us access to some handy data about the invocation that we are stubbing, in particular:

Screen Shot 2017-03-30 at 21.13.25

we can then use the arguments of the invocation of the stubbed method to define our Answer, for example:

Screen Shot 2017-03-30 at 21.25.52

We decided to take the List of OpportunityLineItem and copy for three times, instead of two of the real implementation.

but, first let’s have a look at the method we want to test:

Screen Shot 2017-03-30 at 21.43.56

Let’s concentrate for a second on the List<OpportunityLineItem> oppLines returned by the selector, that is then passed to the service, and saved in the DB through the unit of work.

As we said previously the doStuff method have a side effect on the Opportunity lines, now we have to test that the registerDirty is called with the expected lines:

Screen Shot 2017-03-30 at 21.48.21.png

breaking down the method we have the stubbing

Screen Shot 2017-03-30 at 21.58.29

where mockLines is

Screen Shot 2017-03-31 at 21.49.29

and since the answer triplicates the lines the expected lines to be registered in the unit of work would be

Screen Shot 2017-03-31 at 21.54.56.png

The Answer is a new powerful tool in your Apex Mocks tool box that would help where the classic stubbing is not enough.

Happy mocking.

The code of those examples can be downloaded from my GitHub repo.

Other Resources:

Advertisements

Verify call’s order in Apex unit tests

Have you ever though to verify the order of a method call in your Apex unit tests?

With Apex Mocks you can.

Sometimes ensure that a method is called after another one can add that plus strength to your unit tests.

Let’s have a look at an example: In our example, I’ll use a hypothetical API service that follows the Enterprise Pattern from the fflib-apex-common. This API performs few reads of data, it process that data and then consolidate it using the fflib_ISObjectUnitOfWork.

Does it sound complicated? Let’s have a look at the code

Screen Shot 2017-03-26 at 12.31.46

This it’s calling three selectors ( Opportunity, OpportunityLineItem and Contact) to read some data, then it calls the doStuff() method to perform some operation on these data, and then it registers some data in the UnitOfWork to be stored permanently.

Let’s say that the order on which the selectors are called matters for the correct reading of the data and we want to test it. (the MY_MOCKS variable is the Fflib_ApexMocks instance).

Screen Shot 2017-03-26 at 12.47.48

In the first part, we mock out the methods that interact with Our API. The magic is in the second part of the test method.

Screen Shot 2017-03-26 at 17.25.31

First of all, we create an instance of the fflib_inOrder to tell to Apex Mocks on which mock instance we want to verify in order. Those are passed as a list of objects together with the fflib_ApexMocks instance, however, the order they appear in that list is not relevant to the final verification.

Then is the time to call the method to test, followed by the three verify to assert the correct order of call.

There are three main differences with a classic Apex Mocks verification, firstly the verify method is called on the fflib_inOrder instance instead of the fflib_ApexMocks instance, then we have to specify explicitly the counter through the calls(Integer times). This is due to the fact that the counters ( times, atLeast, atMost ) are not currently fully implemented for the fflib_InOrder framework.

The last difference with a classic verify is that the order in which the verify are performed make the difference between a passing test and a one that fails. In our example, if we swap line 38 and 39 the test would fail.

Here is another example to show how the inOrder verify behaves;

Screen Shot 2017-03-26 at 17.39.57

this is going to test this part of our API method

Screen Shot 2017-03-26 at 17.41.41

In this test, we can observe that the inOrder with the calls(Integer times) performs a not greedy verification ( because it’s actually called three times ) and the fact that the inOrder is not strict ( in a strict verification the registerDirty is called once and then is called the registerNew ).

To perform a more strict verification we should verify every single call:

Screen Shot 2017-03-26 at 17.51.24

however, this test is not a fully strict verify, due to the not greedy nature of the verification. In fact, if in our example we call the registerNew at line 32 and 33 more times, this test still pass, but it won’t if we reduce them to only one.

With the fflib_InOrder you can finally check not only that your code is doing what you’d expect but that is done in the right order. This gives you the opportunity to write those tests that go forward the code coverage and makes your tests stronger and more descriptive. Happy unit testing.

Happy Mocking!

The code of those examples can be downloaded from my GitHub repo.

Other Resources: