Write a Test Data Factory
By the end of this lesson, you'll be able to:
- Extract a shared LoanTestDataFactory used across every test class in this module
- Give the factory sensible defaults that can be selectively overridden
- Refactor the existing tests to use the factory
Prerequisites: "Build a Bulk-Safe Trigger"
Spotting the duplication across three test classes
LoanCalculationServiceTest, LoanValidationServiceTest, and LoanApplicationTriggerHandlerTest all construct Loan_Application__c-like data with similar values — a textbook case for Module 31's factory pattern, now genuinely justified by real duplication rather than a single, isolated example.
The shared factory
@isTest
public class LoanTestDataFactory {
public static Loan_Application__c createApplication(Decimal amount, Decimal income, Decimal creditScore) {
return new Loan_Application__c(
Requested_Amount__c = amount,
Annual_Income__c = income,
Credit_Score__c = creditScore
);
}
public static Loan_Application__c createQualifyingApplication() {
return createApplication(10000, 50000, 720);
}
}
@isTest— marks the class as test-only.public class LoanTestDataFactory {— a shared factory.public static Loan_Application__c createApplication(Decimal amount, Decimal income, Decimal creditScore) {— takes the values that actually vary between test scenarios.return new Loan_Application__c(— builds the record.Requested_Amount__c = amount,— the amount.Annual_Income__c = income,— the income.Credit_Score__c = creditScore— the credit score.);— closes the constructor call.}— closes the method.- (blank line)
public static Loan_Application__c createQualifyingApplication() {— layers a sensible default on top for tests that just need any application that would pass.return createApplication(10000, 50000, 720);— Module 22's constructor-parameter pattern applied to test data specifically.}— closes the method.}— closes the class.
Refactoring the existing bulk test to use it
@isTest
static void bulkApplicationsAllProcessCorrectly() {
List<Loan_Application__c> applications = new List<Loan_Application__c>();
for (Integer i = 0; i < 200; i++) {
applications.add(LoanTestDataFactory.createQualifyingApplication());
}
Test.startTest();
insert applications;
Test.stopTest();
// ... assertions unchanged ...
}
@isTest— marks the test method.static void bulkApplicationsAllProcessCorrectly() {— the same test as before.List<Loan_Application__c> applications = new List<Loan_Application__c>();— unchanged.for (Integer i = 0; i < 200; i++) {— unchanged.applications.add(LoanTestDataFactory.createQualifyingApplication());— only the data-construction line changed, now delegating to the factory.}— closes the loop.- (blank line)
Test.startTest();— unchanged.insert applications;— unchanged.Test.stopTest();— unchanged.- (blank line)
// ... assertions unchanged ...— same test, same assertions, same result — exactly the "behavior unchanged, structure clearer" outcome from every refactoring lesson since Module 12.}— closes the test method.
Exercise
Add a createDecliningApplication() convenience method to LoanTestDataFactory using a credit score below 600.
Show hint
return createApplication(10000, 50000, 550);
Write a Test Data Factory 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
With three test classes now written, the repeated "build a Loan_Application__c with these fields" setup is worth extracting into a shared factory — Module 31's Lesson 8, applied at real scale.