In Salesforce development, writing effective tests is crucial for ensuring that your custom logic works as intended. A critical part of testing is generating the right test data to simulate real-world scenarios. This blog post will guide you through creating Apex test data in Salesforce.
By reading this blog, you will learn how to:
Understand why test data matters: Discover the importance of test data and its impact on code reliability.
Create test utility classes: Learn to streamline test data generation with reusable code.
Implement test scenarios: Explore techniques for testing various conditions and outcomes in your code.
Best practices: Get tips on optimizing your test data creation strategies.
Create Apex Test Data
The data from Apex tests is only temporary and is not saved in the database. This signifies that the data inserted by a test method does not persist in the database after it has completed execution. As a result, at the end of a test, there is no need to delete any test data. It is recommended that test utility classes be created to add reusable methods for test data setup.
Also Read: Apex Testing Best Practices: A Step-by-Step Guide
Create a test utility class
Assuming we have a scenario in which we want to prevent account deletion if any related contacts exist for the account. The validation is added using the Account triggers mentioned below.
(
trigger AccountTrigger on Account (before delete) {
//identify if the trigger is running in before delete context
if(Trigger.isBefore && Trigger.isDelete){
//soQL for loop to fetch open contacts associated with the account.
//Prepare the set of account ids.
Set<Id> accountIdFromContacts = new Set<Id>();
for (
Contact objContact : [|
SELECT Id, AccountId
FROM Contact
WHERE AccountId In :Trigger.old
accountIdFromContacts.add (objContact.AccountId) ;
}
//Iterate through the accounts to see if any contacts exist.
for (Account eachAccount: Trigger.old){
if(accountIdFromContacts.contains (eachAccount.Id) ){
eachAccount.addError (
‘Cannot delete account with related contacts.’
) ;
}
}
)
For this example, let’s create an AccountUtility Test utility class with a method called
createAccountsWithContacts that accepts the number of accounts and the number of related contacts to insert for each account. Because the class is annotated with @isTest, it can only be accessed by the test class.
(
@isTest
public class AccountUtilityTest {
//The method accepts the count of accounts and contacts to insert.
public static List<Account> createAccountsWithContacts (
Integer numberOfAccounts, Integer number0fRelatedContacts
//Insert accounts.
List<Account> 1stAccountsToInsert = new List<Account> () ;
for (Integer i=0; i<numberOfAccounts; i++){
1stAccountsToInsert.add (
new Account (Name = ‘Dummy Account ‘+ i)
) ;
}
insert 1stAccountsToInsert;
//create contacts related to the accounts.
if(number0fRelatedContacts != null && numberOfRelatedContacts > 0){
List<Contact> IstRelatedContactsToInsert = new List<Contact> () ;
for (Account eachAccount: 1stAccountsToInsert) {
for (Integer i=0; i<number0fRelatedContacts; i++){
1stRelatedContactsToInsert.add(
new Contact (
LastName = ‘DummyLastName ‘+ i,
AccountId = eachAccount.Id
}
insert lstRelatedContactsToInsert;
}
return lstAccountsToInsert;
}
)
Utilize the test utility class to set up test data and test multiple scenarios.
Now that we have added AccountUtilityTest utility class, we can utilize the methods by using the below syntax. The utility class will return the Account [] with one account record.
(
//Syntax to access the utility class.
List<Account> lstAccounts =
AccountUtilityTest.createAccountsWithContacts (1, 0);
)
We’ll make a test class called Account Trigger Test to test the Account Trigger.
Case 1: Delete a single account with no associated contacts.
(
@isTest (SeeAllData=false)
public class AccountTriggerTest {
@isTest
static void deleteSingleAccountWithoutContactTest (){
List<Account> lstAccounts =
AccountUtilityTest.createAccountsWithContacts (1, 0);
Test. startTest();
List<Database.DeleteResult> result = Database.delete(1stAccounts, false) ;
Test. stopTest () ;
List<Account> 1stAccountsAfterDelete = [SELECT Id FROM Account];
//validating the trigger outcome.
System.assertEquals(1stAccountsAfterDelete.size(), 0);
}
Case 2: Delete multiple accounts with no associated contacts
@isTest (SeeAllData=false)
public class AccountTriggerTest {
lisTest
static void deleteSingleAccountWithoutContactTest (){
List<Account> lstAccounts =
AccountUtilityTest.createAccountsWithContacts(1, 0);
Test. startTest () ;
List<Database.DeleteResult> result = Database.delete(lstAccounts, false) ;
Test. stopTest ( );
List<Account> lstAccountsAfterDelete = [SELECT Id FROM Account];
//validating the trigger outcome.
System.assertEquals(1stAccountsAfterDelete.size(), 0);
lisTest
static void deleteMultipleAccountWithoutContactTest()‹
//call the utility class to create 200 accounts.
List<Account> lstAccounts =
AccountUtilityTest.createAccountsWithContacts(200, 0);
Test. startTest () ;
List<Database.DeleteResult> result = Database.delete(lstAccounts, false) ;
Test. stopTest ();
List<Account> 1stAccountsAfterDelete = [SELECT Id FROM Account];
//validating the trigger outcome.
System.assertEquals(1stAccountsAfterDelete.size(), 0);
}
Case 3: Delete a single account withe associated Contacts.
@isTest (SeeA11Data=false)
public class AccountTriggerTest {
lisTest
static void deleteSingleAccountWithoutContactTest(){
List<Account> 1stAccounts =
AccountUtilityTest.createAccountsWithContacts(1, 0);
Test.startTest();
List<Database.DeleteResult> result = Database.delete(IstAccounts, false) ;
Test.stopTest ();
List<Account> 1stAccountsAfterDelete = [SELECT Id FROM Account];
//validating the trigger outcome.
System.assertEquals(1stAccountsAfterDelete.size(), 0);
@isTest
static void deleteMultipleAccountWithoutContactTest(){
//call the utility class to create 200 accounts.
List<Account> lstAccounts =
AccountUtilityTest.createAccountsWithContacts (200, 0);
Test. startTest() ;
List<Database.DeleteResult> result = Database.delete(IstAccounts, false);
Test. stopTest () ;
List<Account> 1stAccountsAfterDelete = [SELECT Id FROM Account] ;
//validating the trigger outcome.
System.assertEquals(1stAccountsAfterDelete.size(), 0);
@isTest
static void deleteSingleAccountWithContactTest (){
List<Account> lstAccounts =
AccountUtilityTest.createAccountsWithContacts(1, 1);
Test.startrest ();
List<Database.DeleteResult> result = Database.delete(1stAccounts, false);
Test. stoplest ();
List<Account> lstAccountsAfterDelete = [SELECT Id FROM Account];
//validating the trigger outcome.
System.assertEquals(1stAccountsAfterDelete.size(), 0);
}
@isTest
static void deleteSingleAccountWithContactTest (){
List<Account> lstAccounts =
AccountUtilityTest.createAccountsWithContacts (1, 1);
Test. startTest() ;
List<Database.DeleteResult> result = Database.delete(1stAccounts, false);
Test.stopTest () ;|
List<Account> lstAccountsAfterDelete = [SELECT Id FROM Account];
//validating the trigger outcome.
System.assertEquals(1stAccountsAfterDelete.size(), 1);
}
}
Conclusion
Mastering Apex test data creation is a must for Salesforce developers aiming to deliver high-quality, reliable code. By understanding the value of test data, creating reusable utility classes, and setting up realistic scenarios, you’ll boost your ability to craft robust solutions that can handle real-world challenges.
Elevate your Salesforce skills with saasguru today! Start your free trial and gain access to 24+ Salesforce certification courses, over 50 mock exams, and more than 50 Salesforce labs. Embark on your journey to becoming a certified Salesforce expert and fast-track your career growth with hands-on learning.