Write Permission-Based Tests
Learning Objectives
After completing this unit, you’ll be able to:
- Explain the importance of permission-based testing.
- Write permissions-based unit tests.
The Pattern
Many developers are positive that you should write permission tests for your code. This video offers an introduction to permission-based testing.
Permission-based testing can be the most complex testing pattern of all. In part, that’s because permissions can be confusing, and in part it’s because a good set of permissions tests uses both positive and negative test patterns. To write a permissions test, you need to generate not only test data, but also one or more test users. Once you have those, you can write both positive and negative tests and run them as your test users with or without specific permissions.
Let’s take a look at the pattern for permissions tests:
- Generate or load your test data.
- Create users with appropriate permission sets.
- Start a
System.runAs(user)
block. - Execute your negative or positive test inside the
System.runAs(user)
block, as we’ve seen in units 3 and 4.
The permission set testing case is the one case where you do not need to create your own test data. A permission set is a record detailing which permissions are granted. These permission set records are effectively metadata and not data. As they are part of your organization configuration, you use existing permission sets when testing. Thus, in your tests, you only need to create a test user and assign an existing permission set to that user.
The package you installed in unit 1 of this module contains a permission set called Private_Object_Access
and a custom object whose default sharing is set to private. With that in place, let's look at what a permission-set test looks like.
- Open VS Code.
- In the Explorer sidebar, right-click the folder
classes
, then choose SFDX: Create Apex Class. - Name the new class
PermissionsTests
, and accept the default directory. - Replace the contents of the class with the following code.
@IsTest private class PermissionsTests { @TestSetup static void testSetup() { // GIVEN Account a = TestFactory.getAccount('No view For You!', true); Private_Object__c po = new Private_Object__c(Account__c = a.id, Notes__c = 'foo'); insert po; } @IsTest static void testNegativePermissionSet() { // GIVEN User u = new User( ProfileId = [SELECT Id FROM Profile WHERE Name = 'Standard User'].Id, LastName = 'last', Email = 'Cpt.Awesome@awesomesauce.com', UserName = 'Cpt.Awesome.' + DateTime.now().getTime() + '@awesomesauce.com', Alias = 'alias', TimeZoneSidKey = 'America/Los_Angeles', EmailEncodingKey = 'UTF-8', LanguageLocaleKey = 'en_US', LocaleSidKey = 'en_US' ); insert u; System.runAs(u) { // WHEN Test.startTest(); Private_Object__c[] pos = [SELECT Id, Account__c, Notes__c FROM Private_Object__c]; Test.stopTest(); // THEN Assert.areEqual( 0, pos.size(), 'A user without the permission set shouldn\'t see any records'); } } }
- Click File > Save.
- Right-click the file you’re working on, then choose SFDX: Deploy Source To Org.
- Click the Run Test button that appears on the
testNegativePermissionSet
method.
Code Highlights
The test method in our code above demonstrates that users without the permission set cannot see the Private_Object__c
records.
In our @TestSetup
method, we’re creating the Private_Object__c
record associated with an account. Because the sharing model is set to private, only the system can see this record. When we execute the actual test method, we create a new user and execute the query as that user. That results in the new user being unable to see the Private_Object__c
record.