Test Data Factories
By the end of this lesson, you'll be able to:
- Extract repeated test-data setup into a reusable factory method
- Explain why duplicated setup code across test methods is worth refactoring
- Apply Module 12/17/22/23's refactoring habit specifically to test code
Prerequisites: "Testing Triggers: Bulk and Edge Cases"
Spotting duplication across test methods
@isTest
static void test1() {
Account acc = new Account(Name = 'Test Account', Industry = 'Technology');
insert acc;
// ...
}
@isTest
static void test2() {
Account acc = new Account(Name = 'Test Account', Industry = 'Technology');
insert acc;
// ...
}
@isTest— marks the first test method.static void test1() {— one test.Account acc = new Account(Name = 'Test Account', Industry = 'Technology');— every test method needing a validAccountrepeats the exact same setup.insert acc;— saves it.// ...— the rest of this test.}— closes this test method.- (blank line)
@isTest— marks a second test method.static void test2() {— a different test.Account acc = new Account(Name = 'Test Account', Industry = 'Technology');— the exact same setup, duplicated.insert acc;— saves it.// ...— the rest of this test.}— closes this test method — the same duplication problem Modules 12, 17, 22, and 23 each closed out by extracting a shared private method, now showing up in test code specifically.
Extracting a factory method
@isTest
private class AccountRollupServiceTest {
private static Account createTestAccount() {
Account acc = new Account(Name = 'Test Account', Industry = 'Technology');
insert acc;
return acc;
}
@isTest
static void test1() {
Account acc = createTestAccount();
// ...
}
@isTest
static void test2() {
Account acc = createTestAccount();
// ...
}
}
@isTest— marks the class.private class AccountRollupServiceTest {— the class.private static Account createTestAccount() {—private static— callable directly from any@isTest staticmethod in the same class, exactly like the trigger handler's private helpers from Module 22.Account acc = new Account(Name = 'Test Account', Industry = 'Technology');— the one, now-shared setup.insert acc;— saves it.return acc;— hands it back.}— closes the factory method.- (blank line)
@isTest— marks the first test.static void test1() {— a test.Account acc = createTestAccount();— delegates instead of repeating the setup.// ...— the rest of this test.}— closes this test.- (blank line)
@isTest— marks the second test.static void test2() {— a different test.Account acc = createTestAccount();— the same shared factory.// ...— the rest of this test.}— closes this test.}— closes the class.
Any future change to what a "valid test Account" needs happens in exactly one place.
A shared factory class for reuse across multiple test classes
@isTest
public class TestDataFactory {
public static Account createAccount(String name) {
Account acc = new Account(Name = name, Industry = 'Technology');
insert acc;
return acc;
}
public static Book__c createBook(String title) {
return new Book__c(Title__c = title, ISBN__c = '000-0-000-00000-0', Is_Checked_Out__c = false);
}
}
// used from any test class:
Account acc = TestDataFactory.createAccount('Riverbend Farms');
@isTest— marks the class as test-only, but public so it can be called from other test classes.public class TestDataFactory {— for data patterns reused across multiple test classes, not just within one.public static Account createAccount(String name) {— a reusable factory method.Account acc = new Account(Name = name, Industry = 'Technology');— builds it.insert acc;— saves it.return acc;— hands it back.}— closes the method.- (blank line)
public static Book__c createBook(String title) {— a second factory method, for a different object.return new Book__c(Title__c = title, ISBN__c = '000-0-000-00000-0', Is_Checked_Out__c = false);— builds and returns it directly.}— closes the method.}— closes the class.- (blank line)
// used from any test class:— the label for the usage example.Account acc = TestDataFactory.createAccount('Riverbend Farms');— avoids duplicating the same setup logic across every test file in the org — the natural next step once a single class's private helper isn't enough.
Exercise
Extract a private static createTestBook() factory method that inserts and returns a valid Book__c, then use it in a test method.
Show hint
private static Book__c createTestBook() { ...; insert book; return book; }
Test Data Factories Quiz
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
Just like production code, test code accumulates duplication — a test data factory extracts the repeated "build a valid test record" logic into one reusable method, exactly the refactoring instinct from every project module's closing lesson.