Skip to content

Batchable Apex

Wim Velzeboer edited this page Aug 31, 2021 · 1 revision

Batchable Apex

Contents

The purpose of batch apex job is to execute business logic on large amount of records. It is shopped into smaller chunks (e.g. 200 records) and each batch is passed to a Service method containing the business logic.

The batchable class should not perform any business logic self. Its only concern is to get the records (via QueryLocator) that it needs (optionlly add another filter), and then invoke the Service layer.

Example

public class RecalculateRatingBatch implements Database.Batchable<SObject>
{
    private static final Integer SCOPE_SIZE = 200;

    public static Id execute()
    {
        return Database.executeBatch(new RecalculateRatingBatch(), SCOPE_SIZE);
    }

    public Database.QueryLocator start(Database.BatchableContext bc)
    {
        return AccountsSelector.newInstance().queryLocatorAll();
    }

    public void execute(Database.BatchableContext bc, List<SObject> scope)
    {
        AccountsService.recalculateRating((List<Account>) scope);
    }

    public void finish(Database.BatchableContext bc) { }
}
@IsTest
private class RecalculateRatingBatchTest
{
    @IsTest
    static void testBehavior()
    {
        // GIVEN - An Account
        insert new Account(Name = 'Dummy'); // we can't mock QueryLocator, need a record

        fflib_ApexMocks mocks = new fflib_ApexMocks();
        IAccountsService serviceMock = (IAccountsService) mocks.mock(IAccountsService.class);
        Application.Service.setMock(IAccountsService.class, serviceMock);

        // WHEN
        System.Test.startTest();
        RecalculateRatingBatch.execute();
        System.Test.stopTest();

        // THEN
        ((IAccountsService) mocks.verify(serviceMock))
                .recalculateRating(
                        fflib_Match.sObjectsWith(
                                new List<Map<SObjectField, Object>>
                                {
                                        new Map<SObjectField, Object>
                                        {
                                                Account.Name => (Object) 'Dummy'
                                        }
                                }
                        )
                );
    }
}
Clone this wiki locally