Get Hands-On With Apex Assertions
Learning Objectives
After completing this unit, you’ll be able to:
- Write clear and intentional Apex Assertions.
Write Clear and Intentional Apex Assertions
Improve the readability of your Apex code by using the assert methods in the new System.Assert
class that fit the exact conditions that you’re checking for. We still support the existing System
class assert methods. But we also recommend that you start using the new ones soon and that you update your existing code to use them.
Where: This change applies to Lightning Experience and Salesforce Classic in Enterprise, Performance, Unlimited, and Developer editions.
Why: Apex provides three assert methods. System.assert()
, System.assertEquals()
, and System.assertNotEquals()
. While adequate for many use cases, these methods can result in ambiguous or verbose error messages. For example, this Apex code checks for a null value.
System.assertEquals(null, 'null');
null
strings.System.AssertException: Assertion Failed: Expected: null, Actual: null
The new System.Assert
class provides methods that handle all types of logical assertions and comparisons. When you use an assert method intended for a specific condition, the clarity of your Apex code improves. And if the assertion results in an exception, it’s easier to read and understand.
How: Choose a method in the new System.Assert
class that best fits the condition. For example, to assert whether two values are equal, use the Assert.areEqual()
method, which is equivalent to the existing System.assertEquals()
:
String sub = 'abcde'.substring(2); Assert.areEqual('cde', sub);
Here’s an example of checking for null values.
String myString = null; Assert.isNull(myString, 'String should be null');
This example checks that exceptions are thrown from a method you’re testing and that they’re of the expected type.
try { methodUnderTest(); Assert.fail('Exception failure is always an option'); } catch (Exception ex) { Assert.isInstanceOfType(ex, DmlException.class); // Additional assertions }
Get Ready for the Hands-on Challenge
In the hands-on challenge below, you’ll have an opportunity to work with assert methods to write clear and intentional Apex assertions.
Launch the org you’ll use for the hands-on challenge, then do the following prework.
- Create a class
- Name:
TestFactory
- Replace the contents of the class with the following code.
- Name:
@isTest public class TestFactory { public static Account getAccount(String accountName, Boolean doInsert) { Account account = new Account(Name = accountName); if (doInsert) { insert account; } return account; } public static Contact getContact(Id accountId, String firstName, String lastName, Boolean doInsert){ Contact contact = new Contact( FirstName = firstName, LastName = lastName, AccountId = accountId ); if (doInsert) { insert contact; } return contact; } public static void generateAccountWithContacts(Integer numContacts) { Account account = getAccount('default account ltd', true); List<Contact> contacts = new List<Contact>(); for (Integer i = 0; i < numContacts; i++) { String firstName = 'Contact'; String lastName = 'Test' + i; contacts.add(getContact(account.Id, firstName, lastName, false)); } insert contacts; } public static Opportunity[] generateOppsForAccount(ID accountId, Decimal amount, Integer numOpps){ List<Opportunity> oppsForAccounts = new List<Opportunity>(); for (Integer i = 0; i < numOpps; i++) { Opportunity opp = new Opportunity( Name = 'Account ' + i, AccountId = accountId, Amount = amount, CloseDate = Date.today().addDays(5), StageName = 'Prospecting' ); oppsForAccounts.add(opp); } return oppsForAccounts; } public static User generateUser(String profileName) { UserRole userRole = new UserRole( DeveloperName = 'TestingTeam', Name = 'Testing Team' ); insert userRole; String uniqueEmail = 'Cpt.Awesome' + DateTime.now().getTime() + '@th.example.com'; User userForInsert = new User( ProfileId = [SELECT Id FROM Profile WHERE Name = :profileName].Id, LastName = 'lastName', Email = uniqueEmail, Username = uniqueEmail, CompanyName = 'Testing Co', Title = 'Captain', Alias = 'alias', TimeZoneSidKey = 'America/Los_Angeles', EmailEncodingKey = 'UTF-8', LanguageLocaleKey = 'en_US', LocaleSidKey = 'en_US', UserRoleId = userRole.Id ); insert userForInsert; return userForInsert; } }
- Create a class
- Name:
DataGenerationTest
- Replace the contents of the class with the following code.
- Name:
@isTest private class DataGenerationTest { @testSetup static void dataCreation() { Account account = TestFactory.getAccount('Muddy Waters Inc.', true); Contact contact = TestFactory.getContact(account.Id, 'Muddy', 'Waters', true); Opportunity opp = New Opportunity(); opp.Name = 'Long lost record'; opp.AccountId = account.Id; opp.CloseDate = Date.today().addDays(14); opp.StageName = 'Prospecting'; insert opp; } @isTest static void testBruteForceAccountCreation() { List<Account> accts = new List<Account>(); Test.startTest(); accts = [SELECT Id FROM Account]; Test.stopTest(); System.assert(accts.size() > 0, 'Was expecting to find at least one account created on the Test Setup'); } @isTest static void testUseTestFactoryToCreateAccountsWithContacts() { List<Account> accts; List<Contact> contacts; TestFactory.generateAccountWithContacts(5); Test.startTest(); accts = [SELECT Id FROM Account]; contacts = [SELECT Id FROM Contact]; Test.stopTest(); System.assert(accts.size() > 0, 'Was expecting to find at least one account created'); System.assert(contacts.size() == 6, 'Was expecting to find 6 contacts'); System.assertNotEquals(accts.size(), contacts.size(), 'Was expecting there to be a different number of account and contacts'); } @isTest static void testAtTestSetupMethodsRule() { List<Opportunity> opps = [SELECT Id, AccountId FROM Opportunity]; System.assertEquals(1, opps.size(), 'Expected test to find a single Opp'); } }