Mocking fundamentals – simple mocks without frameworks

What you have to know before giving up with mocks

hello-i-m-nik-v8pL84kvTTc-unsplash– Photo by Hello I’m Nik 🇬🇧 on Unsplash

Maybe you have heard about the mocking technique a lot, but never understood very well how it works or doubted if it is really worthwhile. After reading this post, you’ll better understand the pillars of such technique, why it is good for unit testing and how apply it in your application without the need of a framework.

In a future post, I’ll show you the steps to progressively transition from integration tests to real unit tests and how to adopt the popular ApexMocks framework. That will really make the difference to your daily work. However, you’ll get better results if you first let the mocking principles to mature in your mind.

Why to use mocks?

I like to define it as follows: Mocking is a technique in software development that helps to test well architected applications.

Well, the presence of mocks in the tests of an application doesn’t mean it is well architected. Though, in my experience, the absence of them is a good indicator that probably it is not.

The technique as such doesn’t guide you building a right architecture, but combining it with others like BDD, changes the game. Aiming to apply the whole theoretical aspects from day one, might sound overwhelming, but it is not an “all or none”. One will naturally bring the other though. This is why, in this post, I will be focused on giving you the tips you need to do mocks and really get their benefits.

So, why should I implement mocks? What are the promised benefits?

Actually there are many, that are even more noticeable in the Salesforce platform. With mocks you can:

  • Reduce the execution time of your tests. Thus, get quicker CI/CD.
  • Decouple unit tests from the implementation of the other classes. Get tests aligned with the Open Closed principle. Test that don’t break easily.
  • Test wider and more complex scenarios.
  • Ensure each layer is independent from the others (SOC).
  • Allow coding real unit tests, not only integration tests.

In summary, you get fast, more reliable and better real unit tests.

About the last point in the list, it is important to note that you’ll still need to create some integration tests. Those will cover the non programatic aspects of your app and ensure your services work well as a whole.

It is easy to give up

But I challenge you to not doing it. Hopefully, after reading this post you’ll feel more engaged to use mocks.

For developers not used use mocks, it is hard to see the aforementioned benefits of that technique. They easily get absorbed by an awkward feeling of insecurity and quickly get misguided conclusions:

In this way I’m not really testing my application. I’m actually faking it to ensure it pass through certain lines and if something changes, my tests will break easily.

The truth is that it is hard to change that mindset and use mocks when you have been long time only doing integration tests. Your subconscious tricks you into continuing to see unit tests as a data input-output check in a specific user context or scenario, sometimes driven by the 75% coverage goal. You would feel unsafe from failures otherwise. And that is often closely related with applications with certain lack of separation of concerns which makes mocks to seem even more pointless.

I can say all this because, long time ago, I was also one of those devs looking skeptically to the fellow that was instructing me. Fortunately I didn’t end up giving up with mocks, and tried to get why the experts in the field were that fans of mocks. In a later on, I got to understand that they are just a part of a whole. An important tool we all must know, but it turns out to be quite complicated to understand at the beginning. Partially because of the huge amount of misleading information one can find nowadays out there.

Another fact I found that keeps devs away from mocks is the need to build or implement a mocking framework. I personally found the definition of the StubProvider Interface unhelpful for the ones without previous experience on that topic (e.g. Mockito for Java).

The Wikipedia definition of mock objects is pretty good, but it might sound odd to pure “classic Apex” developers (I’m feeling old now). There are good news, though. The mocking technique is sustained by a very simple principle: the ability to replace, at run time, instances of classes (objects) you are not interested in at that moment by others with customised behaviour.

The essentials

Let’s start right by the our last sentence: “mocking is […] the ability to replace […] objects […] by others with customised behaviour”.

So, if you have a function which behaviour depends on other classes, you can simulate (replace) these “external resources”, so that you can test that your method behaves as expected in all kind of scenarios regardless its dependencies. In a nutshell: you can test just your method and ignore everything else. Pretty neat and clean.

A lot of wording but no code at all. Show me something now!

You are right. So, lets say we have for instance:

public with sharing class House {
    @IsTestVisible
    private Boolean isDoorOpen = false;

    public void openDoor() {
        SecurityService security = new SecurityService();
        Boolean userHasAccess = security.isCurrentUserAllowedToEnter();

        if (!userHasAccess) {
            throw new SecurityException('You do not have access to this house');
        }

        isDoorOpen = true;
    }
}

If we were to test the openDoor method as it is to ensure all the possible variations of the SecurityService class, we’d need to insert a few records like a user and its permissions, permission set assignments, etc. Then use the runAs method to check it works in all our methods. Something like:

@isTest
private class HouseTests {
    @isTest
    private static void openDoor_userHasAccess_doorOpen() {
        // Given
        User userWithAccess = new User(
            FirstName = 'Gregory,
            LastName = 'House',
            //...rest of params);
        insert userWithAccess;

        PermissionSet houseManagementPS =
            [SELECT Id FROM PermissionSet WHERE Name = 'HouseManagement'];
        insert new PermissionSetAssignment(
            AssigneeId = userWithAccess.id,
            PermissionSetId = houseManagementPS.Id);

        // When
        System.runAs(userWithAccess) {
            House standardHouse = new House();
            standardHouse.openDoor();
        }

        // Then
        System.assert(standardHouse.isDoorOpen,
            'The door should be open.');
    }
}

The problematic is obvious here:

  • We need to perform a couple of inserts and a query before testing anything.
  • SecurityService internals will interfere also on the efficiency of the tests.
  • If the SecurityService implementation, we’ll have to amend the HouseTests too!
  • isParallel=true is not allowed when the tests refer to the User object. Slower tests.
  • Tests become more verbose deviating the attention from the important (a flag is set to true or not!).
  • If this test doesn’t fail, it doesn’t mean it is correct. If you remove all the SecurityService code from the House class, the test will still work.

It is reasonable to state that the problem will become bigger as the dependent class grows in complexity. Our objective with the mocking technique is to remove all those problems by producing something like:

@isTest(isParallel=true)
private class HouseTests {
    @isTest
    private static void openDoor_userHasAccess_doorOpen() {
        // Given
        makeSecurityToPass();

        // When
        House standardHouse = new House();
        standardHouse.openDoor();

        // Then
        System.assert(standardHouse.isDoorOpen,
            'The door should be open.');
        verifySecurityHasBeenChecked();
    }
}

This sounds kind of obscure magic, but as I promised, it is pretty simple. We just need a way to tell the openDoor method to use a customised version of the SecurityService class. In other words, we have to replace the class by its mock.

Ways to replace behaviour

We have listed a number of problems for the HouseTests, but they are actually a consequence of a bad design of the House class. Think that we cannot use a different security mechanism if we were creating different kind of houses. That is to say that the House class is tightly coupled with the SecurityService class. The secret: we have to remove the new keyword from the House class. Let’s see how.

Setup

Firs of all, we have to make a little tweak to our SecurityService. Pay attention to the highlighted lines below:

public with sharing class SecurityService
    implements ISecurityService {

    public interface ISecurityService {
        Boolean isCurrentUserAllowedToEnter();
    }

    public Boolean isCurrentUserAllowedToEnter() {
        // security stuff here
    }
}

This is the most important step. Making the class to implement an interface, we made it to be kind of generic. Now, the House class doesn’t need to use a specific instance. It could use the mock object. Let’s create it too:

public with sharing class SecurityServiceMock
    implements SecurityService.ISecurityService {

    public Boolean IsCurrentUserAllowedToEnterValue {get; set;}

    public Boolean isCurrentUserAllowedToEnter() {
        return IsCurrentUserAllowedToEnterValue;
    }
}

Note that I have created an Apex property to let my unit test to set the service’s return value at run time.

This is all setup we need. As I said at the beginning, in a later post I’ll explain how this gets simplified thank to the StubProvider interface and how the powerful ApexMocks framework saves the day. But we have to walk before we run.

Replacement by Dependency Injection

Don’t let the name scare you. Dependency Injection is perhaps the simplest and most popular method to accomplish our goal. In a nutshell, the class that depends on another, gets the instance as a parameter instead of constructing it by its own. I.e. House takes SecurityService as parameter. In this example, the instance is given by the class constructor:

public with sharing class House {
    private Boolean isDoorOpen = false;
    private SecurityService.ISecurityService security;

    public House(ISecurityService security) {
        SecurityService.ISecurityService this.security = security;
    }

    public void openDoor() {
        Boolean userHasAccess = this.security.isCurrentUserAllowedToEnter();
        if (!userHasAccess) {
            throw new SecurityException('You do not have access to this house');
        }

        isDoorOpen = true;
    }
}

An alternative to this, is to add a setter method instead of a specific constructor. Something like public void setService(SecurityService.ISecuritySerivice service). That’d allow changing the behaviour of an existing House instance. It is really up to you.

Now, let’s have a look at how the unit test get’s heavily simplified:

@isTest(isParallel=true)
private class HouseTests {
    @isTest
    private static void openDoor_userHasAccess_doorOpen() {
        // Given
        SecurityServiceMock securityMock = new SecurityServiceMock();
        securityMock.IsCurrentUserAllowedToEnterValue = true;

        // When
        House standardHouse = new House(securityMock);
        standardHouse.openDoor();

        // Then
        System.assert(standardHouse.isDoorOpen, 'The door should be open.');
    }
}

Note that, you can easily test the negative use case and catch the exception. This test is much quicker to run, it can be parallelised, and doesn’t need to know the internal data the SecurityService class needs to success.

The downside of this technique is that, if a class depends on more other classes, you’ll have to add more parameters to the constructor or create additional setter methods. It is worthwhile though!

Replacement by deferring construction

Actually, with dependency injection, we moved the SecurityService construction out from the House class. There are plenty of ways to do the same and we are about to see another one, but this time, the construction will be the SecurityService very own responsibility.

Let’s perform one little tweak more to the SecurityService class:

public with sharing class SecurityService implements ISecurityService {
    @TestVisible ISecurityService serviceInstance;

    public interface ISecurityService {
        Boolean isCurrentUserAllowedToEnter();
    }

    public static ISecurityService getInstance() {
        if (serviceInstance == null) {
            serviceInstance = new SecurityService();
        }
        return serviceInstance;
    }
}

And now, let’s go back to the House class and see how it should be used:

public with sharing class House {
    private Boolean isDoorOpen = false;

    public void openDoor() {
        SecurityService.ISecurityService security =
            SecurityService.getInstance();
        Boolean userHasAccess = security.isCurrentUserAllowedToEnter();

        if (!userHasAccess) {
            throw new SecurityException('You do not have access to this house');
        }

        isDoorOpen = true;
    }
}

I’m sure you already imagine how the unit test will get the advantage of this, but let’s see it in action anyway:

@isTest(isParallel=true)
private class HouseTests {
    @isTest
    private static void openDoor_userHasAccess_doorOpen() {
        // Given
        SecurityServiceMock securityMock = new SecurityServiceMock();
        securityMock.IsCurrentUserAllowedToEnterValue = true;
        SecurityService.serviceInstance = securityMock;

        // When
        House standardHouse = new House();
        standardHouse.openDoor();

        // Then
        System.assert(standardHouse.isDoorOpen,
            'The door should be open.');
    }
}

This is just a handy way I found to move construction of classes out and at the same time remove the need of specifying multiple parameters. But don’t let these examples to limit your imagination. You can find your own method that fits best to your use case.

Probably you’ll find a lot of ideas if you review the behavioural design patterns. At the end of the day, do mocks is just a matter of replacing classes behaviour.

Wrap up and next steps

Now that you have seen the examples, scroll up and check if you can tick all the items listed at the beginning of the article. And all that with just a few simple changes! Let’s summarise them:

  • Make “services” to implement an interface (make them generic).
  • Create mock objects.
  • Delegate construction of objects to other classes.

Like any new skill in life, what you should do next is to practice. Practice a lot. At the beginning you’ll probably find it complex but it will make you get how is your app structured and how you should architect it from now on. You’ll end up creating your own method to do mocks, not necessarily the same ones I have shown you here. At some point it’ll become a second nature.

After some time practicing, I really recommend you to have a look to the Andrew Fawcett’s definition of Separation of Concerns in the first place. It is explained with Salesforce particularities in mind, so it is worth a read.

There are tons of good examples, tutorials, books, etc out there. But now you know what is necessary to differentiate what it is good for you and what it is not. You might for instance have a look to these two Trailhead modules:

When you feel comfortable with that, it will be the moment of applying the promised ApexMocks and I hope to see you in a later post to do it together.

Last but not least, don’t forget the integration tests. I think this recent Twitter thread really hits the spot:

testsAreForProgrammets

This will be always a largely discussed topic, but what it is clear in my opinion, is that unit tests aim to cover the scope of a specific method without its dependencies. That is where the mocking technique excels.

The post ends by saying:

[…] they are written by programmers for programmers.

Your unit tests protect every piece of your software safe from failures or unintended changes. Your integration tests however, will ensure the behaviour of your app works as expected/defined. You’ll still need integration tests, but it will be your responsibility to set the amount and the use cases covered (not code coverage).

My very own experience

I have to say that, my transition from “classic” integration tests to mocked unit tests was kind of easy. ApexMocks was originally created by Paul Hardaker and quickly adopted and extended by the FinancialForce fellows at the time I was working there. I got influenced by the enthusiasm of the brilliant people building it and others with previous experience on the Mockito framework. I still find programmers putting a lot of interest on mocks which is quite nice.

On the other hand, during my years of experience, I have encountered many developers out there who criticised tests with mocks based on a very poor experience, and many others to not have heard about them at all. To be honest, it was hard to understand to me too! Sometimes I also found it difficult to convey the goods of this great tool. It is nobody’s fault. Our minds tend to be a little obstinate. Fear, somehow, is protection. Once we have learn one way to do things, we don’t want to learn another one. Now I’m really convinced mocking is a must to have. So, never give up!

I hope you found this article useful and you are either convinced to use mocks and want to know more, or you have just got convinced to do so. Happy mocking!

Clarity Driven Development

A new mindset for developers

codey meditandoMay the force.com be with you

When one has been coding for a few years, there is a moment in which we look back and realize that our coding practices have changed dramatically. That turning point can take us to the dark side or the light side.

The dark side is not constructive. Perhaps it is our ego that speaks. We could defend the coding practices we adopted during our years of experience, maybe just because someone else said that was the way to go. Although we could be based on very solid arguments, we would be also missing the core concepts that made such reputed software engineer to define them. A Jedi uses the Force.com for knowledge and defense, never for attack. We could still be writing good enough code though (maybe by mistake :-D).

The light side is constructive. When we do an effort to make your code clean and easier to understand, we are thinking on someone, we still don’t know, that will be reading your code. We demonstrate empathy to the developer of that uncertain future. If you are one with the force, you’ll have taken those lessons, not as a recipe, but as the foundations of your own thinking. Your own style. You’ll be ready to appreciate the details and love the code written by those remarkable developers you support.

The programming tools or techniques help building scalable and maintainable software, but you should better have to take the pillars that made them a standard to follow for everyone. You would then be in the light side. Which one you choose, Jedi?

Continue reading “Clarity Driven Development”

Mastering Custom Settings

“Let the games begin”

CustomSettingsStart

Custom Settings feature has remained unchanged for a long time now. You’d say ‘why change something that works so good?’. Absolutely! But are you using them correctly? 

To me it’s been a long time since last time I visited the Custom Settings documentation. So I dived into it and the truth is that, it took me a couple of reads of the Custom Setting methods docs to get all the details.

At the end Custom Settings are quite easy to use once you play around a bit with them, but have some secrets you must know! I got fun finding them and I hope you do too!

Continue reading “Mastering Custom Settings”

One Batch Apex to rule them all (Part II)

Program to interfaces, not implementations

Watch Out!! Bulkified zone!!

In the firsts part of this post, we saw how to isolate the batch apex logic from the operations performed. You can find the full code in the versiononefirst repository.

But today, we are going to extend it further by making our batch apex handler able to perform a list of operations. We’ll also be adding more features and introducing some new concepts as we progress. Get ready… Let’s go!

Continue reading “One Batch Apex to rule them all (Part II)”

One Batch Apex to rule them all (Part I)

Don’t repeat yourself

If you have been working with apex some time, you’ll probably know what a Batch Apex is. Even, you probably created more than one batch apex class to support your most demanding processes, right?

But haven’t you being copying and pasting most of the code, to finally amend some bits of it? Don’t they look too similar at the end? Don’t look around, I won’t tell anybody you did it 🙂 It might not be as bad as it seems, because you probably wanted to provide the same user experience and error handling on all your processes. We’ll work on this now. Are you ready?

Continue reading “One Batch Apex to rule them all (Part I)”

Welcome to version one first!

A long journey to learning.

Recently, Simon Goodyear (Salesforce MVP), during a Salesforce DUG event, said: “Make the version one first“. That’s a good advice, isn’t it? Developers trend to be too perfectionist, indeed. We never feel happy enough with the code we are witting. We would be improving it forever! That sentence inspired me much and that’s because I’m creating this blog.

There are lot of places around the huge internet world were we, developers, can find tutorials, introductions, experiences, experiments, etc, about the Salesforce technology and development in general. Then, why another one?

Because, the three w’s have the information, but finding what you are looking for, and in the desired degree of depth, takes long. This is why I’ll be creating articles, in a level based way. As you have just guessed, there will be a place for the version one, being that the one with less knowledge requirements and followed by a more elaborated ones. Hopefully, some of them will fulfill your needs.

On the other hand, I have been seduced by the irresistible need of express my ideas and findings to the vast world of dev community. Hey mom! Look what I can do! So I’ll do a bit of therapy here 🙂

There will be a place for the other bloggers I admire much. I’ll gather here some of my very favorite blogs in my catablog.

Hope you find useful stuff here. Welcome, and enjoy!

long journey