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:

Advertisements

Counters in the InOrder world: times()

If you are reading this post, probably you had already a glance to my previous post about the Counters. You have probably noticed that the Counters functionality was somehow incomplete. Some of the counter where available for the classic verification but not for the ordered verification.

But not anymore.

Apex Mocks it’s getting more flexible and powerful allowing you to specify strict and loose counters in the inOrder verification.

Let’s go through them one by one and discover their power.

times()

((ISoftwareDeveloper) inOrder.verify(
    mockProductiveDeveloper, MY_MOCKS.times(15))).drinkCoffe();

You can immediately understand that our software is having quite a lot of coffees during the day. But there are some details that need to be mentioned. Let’s have a look at this snippet of pseudo code.

1 softDev.writeSomeCode();
2 softDev.writeSomeCode();
3 softDev.drinkCoffe();

4 softDev.writeSomeCode();
5 softDev.blameSlowNetwork();

6 softDev.writeSomeCode();
6 softDev.writeSomeCode();
7 softDev.gitCommit();

We all are productive developers, so let’s concentrate on the writing of the code, and verify how many times the code has been written.

The times allows us to check how many times the method has been called, and this verification is not strict. What does it mean in code? If we write those verify as separate tests

((ISoftwareDeveloper) inOrder.verify(
    mockProductiveDeveloper, MY_MOCKS.times(2))).writeSomeCode();

((ISoftwareDeveloper) inOrder.verify(
    mockProductiveDeveloper, MY_MOCKS.times(1))).drinkCoffe();

and

((ISoftwareDeveloper) inOrder.verify(
    mockProductiveDeveloper, MY_MOCKS.times(3))).writeSomeCode();

((ISoftwareDeveloper) inOrder.verify(
    mockProductiveDeveloper, MY_MOCKS.times(1))).blameSlowNetwork();

they would both pass.

Yep, you read correctly, they both pass. Why? It’s related to the instances consumed in the verification. For each test, the inOrder goes through all the instances of the mock that we are verifying and sequentially consumes the available invocations.

The first tests first check that writeSomeCode() method is called twice, then looks for the drinkCoffe() and it’s happy. Quite straight forward.

The second Test instead is a bit more tricky. This needs three instances of the writeSomeCode(). Starting from the beginning it has two instances, then have the drinckCoffe() in the middle that is ignored and then it finds the third. After that, the instance available to be verified is blameSlowNetwork().

I’m sure you can tell me how many available instances there are for the writeSomeCode() before our dev would final commit the work on git.

On the other side

((ISoftwareDeveloper) inOrder.verify(
    mockProductiveDeveloper, MY_MOCKS.times(4))).writeSomeCode();

((ISoftwareDeveloper) inOrder.verify(
    mockProductiveDeveloper, MY_MOCKS.times(1))).gitCommit();

and

((ISoftwareDeveloper) inOrder.verify(
mockProductiveDeveloper, MY_MOCKS.times(3))).writeSomeCode();
((ISoftwareDeveloper) inOrder.verify(
mockProductiveDeveloper, MY_MOCKS.times(1))).blameSlowNetwork();
((ISoftwareDeveloper) inOrder.verify(
mockProductiveDeveloper, MY_MOCKS.times(1))).writeSomeCode();

both would fail.

One last detail, the default verification for the InOrder is now “times(1)”. that means that I could happily not specify in my examples whether instead, I kept for readability.

As you can see the power and the flexibility of the InOrder verification have grown with this new counter adding a functionality that was some how missing.

Counters in the InOrder world: atLeast() vs. calls()

This is another chapter of our little story through the ApexMocks counters for the inOrder verification.

You have probably already encountered the first chapter about the inOrder verification.

You have probably noticed that those verifications were some how incomplete in their functionality, but not anymore.

The times() added the possibility to verify the exact number of calls, and then the atLeast() get along. The atLeast() and calls() both set the minimum number of calls that are expected for that method, but they behave differently. The atLeast() is greedy, instead the calls() is not.

Greedy? Not greedy? What does it mean?

To explain the greedy concept we first need to talk about the invocation consumed.

The inOrder stores the invocations methods called on the mocked instance sequentially, in a list. Then when we verify the inOrder goes through this list and “consume” those invocations.

The atLeast(), being greedy, would consume all the invocations that match the method under verification instead, the calls() would consume only those that have been verified.

Let’s see with some pseudo code.

1 softDev.writeSomeCode(); 
2 softDev.writeSomeCode(); 
3 softDev.drinkCoffe(); 
4 softDev.writeSomeCode(); 
5 softDev.blameSlowNetwork(); 
6 softDev.writeSomeCode(); 
7 softDev.writeSomeCode(); 
8 softDev.gitCommit();

performing the following verify

((ISoftwareDeveloper) inOrder.verify( 
     mockProductiveDeveloper, MY_MOCKS.calls(2))).writeSomeCode();

the next available invocation to be verified in this case would be the drinkCoffe() at line 3.

Using the atLeast() instead

((ISoftwareDeveloper) inOrder.verify( 
    mockProductiveDeveloper, MY_MOCKS.atLeast(2))).writeSomeCode();

since it consumes all the invocations that match our method, the next method that is available to be verified is gitCommit() at line 8.

Apex Mocks behaves as close possible to Mockito and for the greedy verification, this page of the Mockito documentation would explain how this concept works.

A special version of the atLeast() is also available: atLeastOnce(). Guess how many time is expected to be called…

The adding of atLeast() counter for the inOrder verification it narrows down the gap of funcionality between ApexMocks and Mockito, giving more flexibility to your mock verification.

Happy mocking.

Stub multiple calls

One of the basics concepts in Mocking is the stubbing.

Wikipedia gives us this definition of stubbing:

“A method stub or simply stub in software development is a piece of code used to stand in for some other programming functionality. ”

In ApexMocks we can stub a method to return a value, or to throw an exception. We can even specify a custom answer when we need more flexibility and power.

Historically the stubbing with ApexMocks can handle only one value at the time.

What if you need to stub a method to return different values or different exceptions each time is called. Well, you could write an Answer and shape what you need, or…

Mockito, from which ApexMock get inspiration, have a specific syntax for that so why ApexMock shouldn’t have as well?

Now you can.

Every one of us has a friend that is not reliable time wise. They great, but they almost cannot make in time at a meeting. Everyone turned up, but not Franck. Then if you call them asking for an estimate of the time they would be there you get each time different time values… and potentially different excuses but for now, let’s keep it simple and concentrate on the times.

MY_MOCKS.when( everyoneTurnedUp.callFrankToFiguredOutWhenHisGonnaArrive()).
    thenReturn(new Time(15 minutes)).
    thenReturn(new Time(20 minutes)).
    thenReturn(new Time(10 minutes)).
    thenThrow(newBeInTimeException('we are all here, hurry up!')). //you are fed up of waiting and shout at Franck to be quicker
    thenReturn(new Time(0 minute)); //he finally arrived

When then you call the callFrankToFiguredOutWhenHisGonnaArrive() this would return 15 the first time, 20 the second, 10 the third, then would throw an exception for the fourth invocation, and for all the other subsequences calls would return zero.

This is possible because those methods can be chained together and define precisely what you need.

To be fair you could write that stubbing in a more compact way using the thenReturnMulti() stubbing method:

MY_MOCKS.when( everyoneTurnedUp.callFrankToFiguredOutWhenHisGonnaArrive()).
    thenReturnMulti(new List<Time>{minutes15, minutes20, minutes10}).
    thenThrow(new BeInTimeException('we are all here, hurry up!')).
    thenReturn(new Time(0 minute));

Similarly, there is the possibility to specify a sequence of Exception that you want to throw sequentially, with the thenThrowMulti() and a list of exceptions as the parameter.

thenReturnMulti() and thenThrowMulti() are not perfectly compliant with Mockito. Mockito uses the same name for the single argument version and the multiple argument version, using an iterable as the parameter of the multi. In Apex we are more limited. The thenReturnMulti() needs to take as a parameter  a list of objects,  and the thenReturn() needs an object. A list of objects is still an object, isn’t it?

If we stubbed N times a method and then the method is called more times than N, after N the value returned would be the one in the last stub. In our case after the fifth time, it would return constantly zero.

One last detail, if you stub the same method multiple times the last stub override the others, for example:

MY_MOCKS.when( everyoneTurnedUp.callFrankToFiguredOutWhenHisGonnaArrive()).
    thenReturn(new Time(5 minutes));

MY_MOCKS.when( everyoneTurnedUp.callFrankToFiguredOutWhenHisGonnaArrive()).
    thenReturn(new Time(10 minutes));

MY_MOCKS.when( everyoneTurnedUp.callFrankToFiguredOutWhenHisGonnaArrive()).
    thenReturn(new Time(11 minutes));

the last stub would override the two previous of 5 and 10 minutes.

The stubbing for sequential calls gives you the flexibility to cover those cases that a simple return is not enough, but with out need to write a custom answer.

Happy Mocking.

 

 

Counters in Apex Mocks verifications

The very core of the Mocks verification checks whether a method has been called or not. Typically with Apex Mocks you can achieve that  with

Screen Shot 2017-04-01 at 11.34.30

Screen Shot 2017-04-01 at 11.35.49

Since the beginning, Apex Mocks aimed to have a syntax that looks like Mockito. Recently Apex Mocks have narrowed the gap with Mockito, getting new counters functionality with a syntax that it’s getting closer to the well know Java mocking library.

Those new functionalities are:

  • times(Integer times)
  • description(String customAssertMessage)
  • atLeast(Integer atLeastTimes)
  • atMost(Integer atMostTimes)
  • atLeastOnce()
  • between(Integer atLeastTimes, Integer atMostTimes)
  • never()

Let’s have a look at some examples on how they work.

The following examples are contained in this ApexMocksExamples project, that you can download and do your Apex Mock experiments. This project is based on the fflib-apex-common and  Enterprise Patterns.

This is the method that we are going to test:

Screen Shot 2017-04-01 at 11.55.58.png

That is not particularly pretty or efficient but helps me to show how to test the calls on the registerDirty() method.

First of all, we need to stub OpportunitiesSelector Screen Shot 2017-04-01 at 11.59.52where mockOpportunities isScreen Shot 2017-04-01 at 12.02.41 then after have defined the mock for the class to test ( Fflib_ISObjectUnitOfWork ) and called the method to test

Screen Shot 2017-04-01 at 12.04.17.png

we can crack on with some verification:

We can verify that the method is called with a specific parameter:

Screen Shot 2017-04-01 at 17.02.52or better, since times(1) is the default behavior with

Screen Shot 2017-04-01 at 17.02.38

It’s easy to guess the next verification;

Screen Shot 2017-04-01 at 17.12.51

In case you want to assert that a method has NOT been called you can use times(0), or more elegantly

Screen Shot 2017-04-01 at 17.11.54

The times() and never method perform a strict validation on the number of times of the method’s calls, but sometimes you need to enforce looser controls and in that case:

atLeast()

Screen Shot 2017-04-05 at 18.26.56

atLeastOnce()

Screen Shot 2017-04-05 at 18.27.42

atMost()

Screen Shot 2017-04-05 at 18.27.03

between()

Screen Shot 2017-04-05 at 18.27.12

would give you more flexibility on your verifications.

The last feature is not a counter, but would help to give more readability and would help to debug a failing test, the description() method

Screen Shot 2017-04-01 at 17.27.08

would add a custom message in case the test fails.

All those methods can be combined together:Screen Shot 2017-04-01 at 17.32.56

With those new features of Apex Mocks you can make your tests even more beautiful.

Happy Mock Testing.

 

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

 

Other Resources:

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: