Advanced 30 min read

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);
    }
}
  1. @isTest — marks the class as test-only.
  2. public class LoanTestDataFactory { — a shared factory.
  3. public static Loan_Application__c createApplication(Decimal amount, Decimal income, Decimal creditScore) { — takes the values that actually vary between test scenarios.
  4. return new Loan_Application__c( — builds the record.
  5. Requested_Amount__c = amount, — the amount.
  6. Annual_Income__c = income, — the income.
  7. Credit_Score__c = creditScore — the credit score.
  8. ); — closes the constructor call.
  9. } — closes the method.
  10. (blank line)
  11. public static Loan_Application__c createQualifyingApplication() { — layers a sensible default on top for tests that just need any application that would pass.
  12. return createApplication(10000, 50000, 720); — Module 22's constructor-parameter pattern applied to test data specifically.
  13. } — closes the method.
  14. } — 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 ...
}
  1. @isTest — marks the test method.
  2. static void bulkApplicationsAllProcessCorrectly() { — the same test as before.
  3. List<Loan_Application__c> applications = new List<Loan_Application__c>(); — unchanged.
  4. for (Integer i = 0; i < 200; i++) { — unchanged.
  5. applications.add(LoanTestDataFactory.createQualifyingApplication()); — only the data-construction line changed, now delegating to the factory.
  6. } — closes the loop.
  7. (blank line)
  8. Test.startTest(); — unchanged.
  9. insert applications; — unchanged.
  10. Test.stopTest(); — unchanged.
  11. (blank line)
  12. // ... assertions unchanged ... — same test, same assertions, same result — exactly the "behavior unchanged, structure clearer" outcome from every refactoring lesson since Module 12.
  13. } — 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);

Salesforce: ○ Not connected Connect
APEX

Execution Results

Run your code to see the result.

Write a Test Data Factory Quiz

1. What justified extracting LoanTestDataFactory at this specific point in the module?

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

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.