Giter Site home page Giter Site logo

joeythomaschaske / lightning-litmus-library Goto Github PK

View Code? Open in Web Editor NEW
1.0 1.0 0.0 216 KB

An apex mocking library inspired by jest

License: MIT License

Shell 0.81% JavaScript 2.29% Apex 96.89%
mocking-library salesforce salesforce-apex salesforce-apex-testing apex

lightning-litmus-library's Introduction

Lightning Litmus Library (L3)

A super fast, lightweight, apex mocking and assertion library.

The L3 library provides a Salesforce testing utility built around the Stub API, enabling developers to mock Apex classes and methods and asserting their invocations with specific parameters and call counts.

The api was inspired by jest and allows for your apex tests to behave like your lwc tests.

Table of Contents

Project Structure

  • lib/src: Contains the source code of the testing utility library.
  • lib/test: Contains test classes for the library.
  • demo/: Contains a demo showcasing the L3 library in action.

Application and Testing Structure

To levergage this library you will need to provide a way for the mock classes to be injected from your tests to the classes that need to be mocked.

This can be as simple as exposing a @TestVisible instance in your classes and having a static method construct instances of your class and returning the mock

Example

public with sharing class AccountsSelector {
    @TestVisible
    private static AccountsSelector instance;

    public static AccountsSelector newInstance() {
        if (instance == null) {
            instance = new AccountsSelector();
        }
        return instance;
    }

    public List<Account> getAccountsById(Set<Id> accountIds) {
        // code
    }
}

When you have a mechanism available to inject the mock you can begin using it.

@IsTest
private class CaseServiceTest {

    @IsTest
    private static void calculatesHighPriorityFromAccountValue() {
        // given
        Account testAccount = new Account(
            Id = TestUtils.generateId(Account.SObjectType),
            AnnualRevenue = 1000000
        );
        Case testCase = new Case(
            AccountId = testAccount.Id
        );

        // mock setup
        MockClass mockAccountSelector = new MockClass();
        MockMethod selectByAccountId = new MockMethod('selectByAccountId', new List<Object> { new List<Account> {testAccount} });
        mockAccountSelector.addMockMethod(selectByAccountId);
        AccountsSelector.instance = (AccountsSelector) Test.createStub(AccountsSelector.class, mockAccountSelector);

        // when
        CaseService.newInstance(new List<Case>{testCase}).calculatePriority();

        // then
        Assert.areEqual('High', testCase.Priority, 'Expected High Priority');

        // mock assertions
        Assert.areEqual(1, selectByAccountId.getTimesCalled(), 'Expected AccountsSelector.selectByAccountId to have been called once');
        Assert.areEqual(new Set<Id>{ testAccount.Id }, selectByAccountId.getNthCalledWith(1)[0], 'Expected AccountsSelector.selectByAccountId to have been called with the test account id');
    }
}

API

MockClass

A MockClass represents a class to be mocked in a unit test. An instance of MockClass holds a list of MockMethods that belong to the class.

Constructor

public MockMethod()

MockClass mockAccountSelector = new MockClass();

addMockMethod

Adds a MockMethod to the MockClass

public void addMockMethod(MockMethod method)

  • method: Adds a MockMethod to the instance that is expected to be called in a unit test.
MockClass mockAccountsSelector = new MockClass();
MockMethod mockSelectById = new MockMethod('selectById', mockListOfAccountsToReturn);
mockAccountsSelector.add(mockSelectById);

handleMethodCall

Called by the Stub API when invoking mocks in unit tests. Not very useful to call directly.

public Object handleMethodCall

  • stubbedObject: The stubbed object
  • stubbedMethodName: The name of the invoked method
  • returnType: The return type of the invoked method.
  • listOfParamTypes: A list of the parameter types of the invoked method.
  • listOfParamNames: A list of the parameter names of the invoked method.
  • listOfArgs: The actual argument values passed into this method at runtime.

MockMethod

A MockMethod represents a method to be mocked in a unit test. An instance of MockMethod holds all the parameters and returns the mocked values when invoked.

Constructor

public MockMethod(String methodName, List<Object> mockValues)

  • methodName: The name of the method to be mocked
  • mockValues: The list of values to return when mocked. Each item in the list represents a return value for an invocation. If a method is called multiple times, then the list should contain multiple values for each invocation.
MockClass mockAccountsSelector = new MockClass();

List<Account> accountsToReturnOnFirstInvocation = new List<Account>{ // specific accounts };
List<Account> accountsToReturnOnSecondInvocation = new List<Account> { // other specific accounts }
List<Object> returnValues = new List<Object> { accountsToReturnOnFirstInvocation, accountsToReturnOnSecondInvocation };

MockMethod mockSelectById = new MockMethod('selectById', returnValues);
mockAccountsSelector.addMockMethod(mockSelectById);

getName

Utility method used by MockClass to confirm mocks aren't overwritten.

public String getName()

MockMethod mockSelectById = new MockMethod('selectById', mockListOfAccountsToReturn);

Assert.areEqual('selectById', mockSelectById.getName());

getTimesCalled

Returns the number of times the method was invoked in a unit test

public Integer getTimesCalled

MockClass mockAccountsSelector = new MockClass();

List<Account> accountsToReturnOnFirstInvocation = new List<Account>{ // specific accounts };
List<Account> accountsToReturnOnSecondInvocation = new List<Account> { // other specific accounts }
List<Object> returnValues = new List<Object> { accountsToReturnOnFirstInvocation, accountsToReturnOnSecondInvocation };

MockMethod mockSelectById = new MockMethod('selectById', returnValues);
mockAccountsSelector.addMockMethod(mockSelectById);

// Call method under test

Assert.areEqual(2, mockSelectById.getTimesCalled());

getNthCalledWith

Returns the list of parameters the method was called with for a specific nth invocation

public List<Object> getNthCalledWith(Integer n)

  • n: The nth invocation to return the invocation parameters for
MockClass mockAccountsSelector = new MockClass();

Id account1Id = TestUtils.generateId(Account.SObjectType);
Id account2Id = TestUtils.generateId(Account.SObjectType);

List<Account> accountsToReturnOnFirstInvocation = new List<Account>{ new Account(Id = account1Id) };
List<Account> accountsToReturnOnSecondInvocation = new List<Account> { new Account(Id = account2Id) };
List<Object> returnValues = new List<Object> { accountsToReturnOnFirstInvocation, accountsToReturnOnSecondInvocation };

MockMethod mockSelectById = new MockMethod('selectById', returnValues);
mockAccountsSelector.addMockMethod(mockSelectById);

// Call method under test

List<Object> 1stInvocationParameters = mockSelectById.getNthCalledWith(1);
List<Object> 2ndInvocationParameters = mockSelectById.getNthCalledWith(2);
Assert.areEqual(account1Id, 1stInvocationParameters[0]);
Assert.areEqual(account2Id, 2ndInvocationParameters[0]);

Gotchas

  • Static methods cannot be mocked by the stub api and thus affects this library as well.
  • When mocking void methods, make sure you specify null as the return type. The stub api expects a return value regardless of if the method actually returns one.
  • Unit tests are not a substitue to integration tests. Integration tests are still needed to make sure your application can run at scale and adhere to all the governor limits.

lightning-litmus-library's People

Contributors

joeythomaschaske avatar

Stargazers

 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.