The Great Salesforce Job Market Reset
December 09, 2024
By Shumon Saha
Sandboxes are frequently used by anyone building on the Salesforce platform to validate changes, ensuring no disruption to the existing configuration will occur. Everyone wants to avoid nasty surprises at all costs, which is why you should simulate data that exists in your org (known as sandbox seeding).
There are different types of Salesforce sandboxes, one type copies your entire production data, and some types don’t copy any data; however, when you create or refresh a sandbox, there is an option to run an Apex Class that we can write to add sample data.
Would you like your new Developer sandboxes to emerge, fully ready, set up, and brimming with sample data like this:
In this guide, I’ll show you how.
Look no further… Developer sandboxes don’t come with sample records; however, when you create or refresh a sandbox, there is an option to run an Apex Class implementing the SandboxPostCopy interface.
Let’s use this feature to auto-populate new sandboxes with sample records.
Without further ado, let’s jump straight in. Our simple example will create 50 Accounts and 300 related Contacts upon sandbox refresh.
The prerequisite is that you need to have an Enterprise Edition org. As per good habits, don’t tinker around in production. Instead, promptly create a sandbox, say “Dev1”, and log into Dev1.
Download these two CSVs of sample accounts and sample contacts…
…and upload them into Static Resources as Account_csv and Contact_csv.
I used Mockaroo to create the above files. [Read about it here].
global class PrepareMySandbox implements SandboxPostCopy {
global void runApexClass(SandboxContext context) {
/*
* Insert sample Accounts
*/
StaticResource accountStaticResource = [select Body from StaticResource
where Name = 'Account_csv'];
String accountCsv = accountStaticResource.Body.toString();
Account[] accountList = new Account[] {};
for(String row : accountCsv.split('\n')) {
String[] column = row.split(',');
accountList.add(new Account(
Name = column[0],
BillingState = column[1],
Phone = column[2],
Type = column[3]
));
}
insert accountList;
/*
* Use a Map to avoid creating an unnecessary External ID field on Account
*/
Map<String, Id> accountMap = new Map<String, Id>();
for (Account acc : accountList) {
accountMap.put(acc.Name, acc.Id);
}
/*
* Insert related Contacts
*/
StaticResource contactStaticResource = [select Body from StaticResource
where Name = 'Contact_csv'];
String contactCsv = contactStaticResource.Body.toString();
Contact[] contactList = new Contact[] {};
for(String row : contactCsv.split('\n')) {
String[] column = row.split(',');
contactList.add(new Contact(
FirstName = column[0],
LastName = column[1],
AccountId = accountMap.get(column[2]),
Title = column[3],
Phone = column[4],
Email = column[5]
));
}
insert contactList;
}
}
@isTest class PrepareMySandboxTest {
@isTest static void testMySandboxPrep() {
Test.startTest();
Test.testSandboxPostCopyScript(
new PrepareMySandbox(),
UserInfo.getOrganizationId(),
UserInfo.getOrganizationId(),
UserInfo.getOrganizationName()
);
Test.stopTest();
System.assertEquals(50, [select count() from Account]);
System.assertEquals(300, [select count() from Contact
where AccountId <> null]);
}
}
Outbound Change Set in Dev1 Sandbox:
Inbound Change Set in Production:
Now that everything is in production, we can finally test it by simply creating a sandbox, say Dev2.
Don’t forget the Apex class:
And voilà! Sample Accounts and related Contacts in Dev2 – can things get any simpler?
This is a great way to populate your sandboxes with data. However, there are a few considerations to bear in mind:
Data loading is one example of what we can achieve using the SandboxPostCopy. With a bit of creativity, more can be automated during a refresh, such as:
Comments: