Advanced 30 min read

Testing Triggers: Bulk and Edge Cases

By the end of this lesson, you'll be able to:

  • Write a bulk test inserting 200 records to verify a trigger stays governor-limit-safe
  • Write edge-case tests for a trigger's boundary conditions
  • Connect this back to Module 27's manual "test with multiple records" lesson

Prerequisites: "Testing Exceptions"

A bulk test, automated

@isTest
private class OpportunityTriggerHandlerTest {
    @isTest
    static void bulkClosedWonUpdateStaysWithinLimits() {
        Account acc = new Account(Name = 'Test Account');
        insert acc;

        List<Opportunity> opportunities = new List<Opportunity>();
        for (Integer i = 0; i < 200; i++) {
            opportunities.add(new Opportunity(
                Name = 'Deal ' + i, AccountId = acc.Id, StageName = 'Prospecting',
                CloseDate = Date.today(), Amount = 1000
            ));
        }
        insert opportunities;

        Test.startTest();
        for (Opportunity opp : opportunities) {
            opp.StageName = 'Closed Won';
        }
        update opportunities;
        Test.stopTest();

        Account updated = [SELECT Total_Won_Revenue__c FROM Account WHERE Id = :acc.Id];
        System.assertEquals(200000, updated.Total_Won_Revenue__c);
    }
}

This is Module 26's AccountRollupService feature, finally given the automated bulk test Module 26 itself only verified manually — 200 Opportunities, one bulk update, and an assertion confirming the rollup handled every single one correctly.

The new-vs-new edge case, automated

@isTest
static void overlappingRequestsInSameBatchAreBlocked() {
    List<Leave_Request__c> batch = new List<Leave_Request__c>{
        new Leave_Request__c(Employee_Name__c = 'Ben', Start_Date__c = Date.newInstance(2026, 5, 1), End_Date__c = Date.newInstance(2026, 5, 5), Status__c = 'Pending'),
        new Leave_Request__c(Employee_Name__c = 'Ben', Start_Date__c = Date.newInstance(2026, 5, 3), End_Date__c = Date.newInstance(2026, 5, 8), Status__c = 'Pending')
    };

    try {
        insert batch;
        System.assert(false, 'Expected a DmlException from the overlap validation');
    } catch (DmlException e) {
        System.assert(e.getMessage().contains('overlaps with another request'));
    }
}

This is Module 27's exact new-vs-new manual verification, now automated and permanent — this specific edge case (which only exists when multiple records are inserted together) gets its own dedicated, always-running test.

Why triggers specifically need this category of test

A trigger's most dangerous bugs — SOQL/DML-in-a-loop (Module 25), recursion (Module 24), a batch-only edge case (Module 27) — are exactly the ones a single-record manual check can never surface. Every trigger this course has built deserves at least one bulk test (200 records) and one test per genuinely batch-specific edge case, as a matter of course, not an afterthought.

Exercise

Write a bulk test inserting 200 Leave_Request__c records for 200 different employees (no overlaps) and asserting they all insert successfully.

Show hint

Vary Employee_Name__c per record so none of them actually overlap with each other.

APEX

Testing Triggers: Bulk and Edge Cases Quiz

1. Why does a trigger deserve a bulk test with 200 records, not just a single-record test?

Log in to submit the quiz and save your score.

My Notes

Log in to keep private notes on this lesson.

Questions about this lesson

No questions yet — be the first to ask.

Log in to ask a question about this lesson.

Summary

This lesson formalizes Module 27's manual multi-record verification into automated bulk and edge-case tests — the single most important category of test for any trigger.