Salesforce Dictionary - Free Salesforce GlossarySalesforce Dictionary
Salesforce Developer
medium

What are the patterns for high-quality Apex unit tests?

Beyond just hitting 75% coverage — meaningful tests follow recognisable patterns.

Pattern 1: Arrange / Act / Assert (AAA).

`apex @isTest static void testAccountUpdate() { // Arrange Account a = new Account(Name='Test', Phone='555-0000'); insert a;

// Act Test.startTest(); a.Phone = '555-1234'; update a; Test.stopTest();

// Assert Account refreshed = [SELECT Phone FROM Account WHERE Id=:a.Id]; System.assertEquals('555-1234', refreshed.Phone); } `

Pattern 2: Test data factory.

apex public class TestDataFactory { public static List<Account> createAccounts(Integer n) { List<Account> accs = new List<Account>(); for (Integer i = 0; i < n; i++) accs.add(new Account(Name='Test '+i)); insert accs; return accs; } }

Reusable, factory accepts overrides for variations.

Pattern 3: Bulk testing. Always test with at least 200 records to confirm bulkification.

apex @isTest static void testBulk() { List<Account> bulk = TestDataFactory.createAccounts(200); Test.startTest(); update bulk; // 200 records exercise governor limits Test.stopTest(); }

Pattern 4: Negative testing. Confirm errors fire for bad input.

apex try { insert new Account(); // missing required Name System.assert(false, 'Should have thrown'); } catch (DmlException e) { System.assert(e.getMessage().contains('REQUIRED_FIELD_MISSING')); }

Pattern 5: Mock externals.

apex Test.setMock(HttpCalloutMock.class, new MyMock());

Pattern 6: System.runAs for permission tests.

apex User testUser = createTestUser('Standard User'); System.runAs(testUser) { // run code as a non-admin user, confirm sharing/permissions enforced }

Pattern 7: Assert messages. Always include a meaningful message in assertions.

apex System.assertEquals(expected, actual, 'Phone update should have propagated');

Anti-patterns:

  • @isTest(SeeAllData=true) — tests depending on org data are flaky.
  • "Coverage tests" with no assertions — pump up coverage without verifying behaviour.
  • Tests with no setup that pass against any code change — they aren't testing anything.
  • Tests with hard-coded Ids — break in any new org.
  • Tests that depend on order of execution — non-deterministic.

A good test reads like specification: "given X, when Y, then Z."

Why this answer works

Senior. The full pattern catalog and the anti-pattern list show test maturity.

Follow-ups to expect

Related dictionary terms