Salesforce unit test data setup framework

Why do we need a test data setup framework

Because it is almost mandatory to generate a set of test data for each test case. And the work is tedious. Consider the following code:


@isTest 
public class SampleTestClass
{
	@isTest
	static void sampleTestMethod()
	{
		Account a = new Account();
		a.Name = 'Test Account';
		a.Active__c = 'Yes';
		insert a;

		Contact c = new Contact();
		c.accountId = a.Id;
		c.firstName = 'Test First Name';
		c.lastName = 'Test Last Name';
		//... Other mandatory fields.
		insert c;

		Opportunity o = new Opportunity();
		//...
	}
}

If you have written some unit tests in Salesforce, you must be familiar with this. Tedious, isn’t it? You need to write this test data preparation code for each single unit test case. And usually, it is much longer than the actual code itself.

In order to resolve this. Salesforce has provided a test utility class solution for this: Common Test Utility Classes for Test Data Creation . It is better than the original way. But it still has very obvious disadvantages: 

  1. It lacks flexibility. While you can choose a certain set of fields to be provided via parameter list, you still want to keep the parameter list shorter because otherwise, it will still be tedious to prepare the data. So it is hard to prepare identical data for each test case without losing convenience.
  2. Test Utility class is still kind of God object which is anti-pattern.

Introduction to test data setup framework

In order to resolve this problem, I have created a very simple framework. The base object is as below:


public abstract class UthSobject 
{
    private List<SObjec> soList = new List<SObject>();

    public abstract SObject generateRecord();

    public virtual SObject createInstance()
    {
        SObject so = generateRecord();
        insert so;
        return so;
    }

    public virtual void registerRecord()
    {
        SObject so = generateRecord();
        soList.add(so);
    }

    public virtual List<SObject> createList()
    {
        if(soList.size() > 0) {
            insert soList;
        }

        return soList;
    }
}

The usage

It is simple to use this framework. Suppose we need to create a record for Account in our test class. First we need to create a child class of UthSObject called UthAccount:


public class UthAccount extends UthSobject
{
	public String accName {get; set;}

	public UthAccount()
	{
		accName = 'Test Account';
	}

	public override SObject GenerateRecord()
	{
		Account a = new Account();
		a.Name = accName;

		return a;
	}
}

This is reusable so you only need to do this once.

And in our unit test class:


@isTest
public class SampleTestClass
{
	@isTest
	static void sampleTestMethod()
	{
		UthAccount accountHelper = new UthAccount();
		//Create one record
		Account a = (Account)accountHelper.createInstance();

		//Create a list of Account
		for(Integer i = 0; i < 10; i++) 
		{
			accountHelper.accName = 'TestAccount' + i;
			accountHelper.registerRecord();
		}

		List<Account> accList = (List<Account>)accountHelper.createList();
	}
}

Advantages

You can put the default value of every single field you want in the class constructor. And you don’t need to worry about the flexibility at all, you just reset the value if you need before persisting it into database. And you can generate one single record as well as a list without worry about the bulkification issue.

Github Page

There is a dedicated github page for this framework:

Salesforce Test Data Setup Framework

You can leave comments about this framework either by commenting in this post, or open an issue in the Github page. 

Next Post

TestSetup annotation – pros and cons

Subscribe to Sfdcinpractice

Subscribe to get the latest blogs and tutorials of sfdcinpractice. No spam, no trash, only the awesome posts from sfdcinpractice. 

Leave a Reply

Your email address will not be published / Required fields are marked *