Skip to content

Undelete

Mock undelete operations in unit tests to avoid actual database undeletes.

WARNING

The DML.mock() and DML.retrieveResultFor() methods are @TestVisible and should only be used in test classes.

TIP

  • No database operations: Mocked undeletes don't touch the database
  • Results are captured: All operation details are available via DML.retrieveResultFor()
  • Selective mocking: Use undeletesFor() to mock specific SObject types while allowing others to execute

Example

apex
public class AccountService {
    public void restoreDeletedAccounts() {
        List<Account> accounts = [SELECT Id FROM Account WHERE IsDeleted = true ALL ROWS];

        new DML()
            .toUndelete(accounts)
            .identifier('AccountService.restoreDeletedAccounts')
            .commitWork();
    }
}
apex
@IsTest
static void shouldRestoreDeletedAccounts() {
    // Setup
    DML.mock('AccountService.restoreDeletedAccounts').allUndeletes();

    // Test
    Test.startTest();
    new AccountService().restoreDeletedAccounts();
    Test.stopTest();

    // Verify
    DML.Result result = DML.retrieveResultFor('AccountService.restoreDeletedAccounts');

    DML.OperationResult accountResult = result.undeletesOf(Account.SObjectType);
    Assert.isFalse(accountResult.hasFailures(), 'No failures expected');
}

allUndeletes

Mock all undelete operations regardless of SObject type.

Signature

apex
DML.mock(String identifier).allUndeletes();

Class

apex
public class DataService {
    public void restoreDeletedRecords() {
        List<Account> accounts = [SELECT Id FROM Account WHERE IsDeleted = true ALL ROWS];
        List<Contact> contacts = [SELECT Id FROM Contact WHERE IsDeleted = true ALL ROWS];

        new DML()
            .toUndelete(accounts)
            .toUndelete(contacts)
            .identifier('DataService.restoreDeletedRecords')
            .commitWork();
    }
}

Test

apex
@IsTest
static void shouldMockMultipleSObjectTypes() {
    // Setup
    DML.mock('DataService.restoreDeletedRecords').allUndeletes();

    // Test
    Test.startTest();
    new DataService().restoreDeletedRecords();
    Test.stopTest();

    // Verify
    DML.Result result = DML.retrieveResultFor('DataService.restoreDeletedRecords');

    Assert.areEqual(2, result.undeletes().size(), '2 SObject types mocked');
}

undeletesFor

Mock undelete operations only for a specific SObject type. Other SObject types will be undeleted in the database.

Signature

apex
DML.mock(String identifier).undeletesFor(SObjectType objectType);

Class

apex
public class DataService {
    public void restoreDeletedRecords() {
        List<Account> accounts = [SELECT Id FROM Account WHERE IsDeleted = true ALL ROWS];
        List<Contact> contacts = [SELECT Id FROM Contact WHERE IsDeleted = true ALL ROWS];

        new DML()
            .toUndelete(accounts)
            .toUndelete(contacts)
            .identifier('DataService.restoreDeletedRecords')
            .commitWork();
    }
}

Test

apex
@IsTest
static void shouldMockOnlyAccountUndeletes() {
    // Setup - Mock only Account undeletes
    DML.mock('DataService.restoreDeletedRecords').undeletesFor(Account.SObjectType);

    // Test
    Test.startTest();
    new DataService().restoreDeletedRecords();
    Test.stopTest();

    // Verify
    DML.Result result = DML.retrieveResultFor('DataService.restoreDeletedRecords');

    Assert.areEqual(2, result.undeletes().size(), '2 SObject types in result');
    // Account was mocked, Contact was actually undeleted
}

Retrieving Results

Use DML.retrieveResultFor() to access the mocked operation results.

Signature

apex
DML.Result result = DML.retrieveResultFor(String identifier);

Class

apex
public class AccountService {
    public void restoreAccount(Id accountId) {
        new DML()
            .toUndelete(accountId)
            .identifier('AccountService.restoreAccount')
            .commitWork();
    }
}

Test

apex
@IsTest
static void shouldAccessRecordResults() {
    // Setup
    DML.mock('AccountService.restoreAccount').allUndeletes();

    // Test
    Test.startTest();
    new AccountService().restoreAccount(DML.randomIdGenerator.get(Account.SObjectType));
    Test.stopTest();

    // Verify
    DML.Result result = DML.retrieveResultFor('AccountService.restoreAccount');
    DML.OperationResult opResult = result.undeletesOf(Account.SObjectType);

    Assert.areEqual(Account.SObjectType, opResult.objectType(), 'Should be Account type');
    Assert.areEqual(DML.OperationType.UNDELETE_DML, opResult.operationType(), 'Should be UNDELETE operation');
    Assert.isFalse(opResult.hasFailures(), 'Should have no failures');
}

Released under the MIT License.