Practice Exams:

Salesforce Certified Sharing and Visibility Designer – Programmatic Sharing Part 3

  1. 3.3- Unit Tests for Programmatic Apex Sharing

This is section three, Programmatic Sharing, and this lecture is about unit tests for programmatic Apex sharing. The topics of this lecture are test classes in apex system that assert methods test start test and test stop test methods and system that run as method. In general, testing your work is crucial. It is done too. Make sure that there are no errors. Make sure that the expected output is working as expected as per the code specifications, and be able to deploy into the production environment. You cannot deploy your code to the production environment unless it is tested.

Now, how can testing be performed? The first way is manually through the user interface. This is done when you add a functionality and then see if it is working by testing it in the user interface. As an example, you just shared a record with a user. To test this, you log in as the user that you shared this record with and see if this user can access this record. This method of testing is important, but it is prone to errors and will not catch all of the use cases for your application.

The second way is automatically through unit tests, which are special classes and methods that are made for testing only and that automate the testing procedure. Apex unit tests are class methods that verify whether a piece of code is working properly. To make it simple, think of a test method as an Apex code that tests another Apex code.

And in Salesforce, testing is required for deployment to the production environment. You cannot deploy from a sandbox to a production environment without testing. In addition to being critical for quality assurance, apex unit tests are required for deploying and distributing Apex. But why testing is required? Well, Salesforce runs in a multitenant environment. Many orgs share the same instance, and for that, any Apex code should be tested before being deployed. Apex code can only be written in a sandbox environment or a developer. org, and not directly in the production environment.

And after being developed in a sandbox or a developer environment, apex code can be deployed to a production environment. And it can also be made into packages and distributed via the App Exchange. Now, what are the requirements to be able to deploy Apex to the production environment or to the App Exchange? In order to be able to deploy Apex to the production environment or to the App Exchange, at least 75% of your entire salesforce organization.

Apex code must be covered by unit tests. And note that when deploying to production, each unit test in your is executed. Calls to system that debug are not counted as part of Apex code coverage. And test methods and test classes are not counted as part of the Apex code coverage. On top of the 75% required coverage, each unit test must pass and each trigger must have some coverage. And note that code coverage is calculated by dividing the number of unique Apex code lines executed during your test method execution by the total number of Apex code lines in all of your triggers and classes.

Now, how to execute test classes? There are many ways to do so. We can do that via the setup page, which can be done in three different places. The first place is from the Apex Test execution page. The second is from the Apex Classes page list where we can run the run all tests. And the third is from a specific Apex class where we can run a specific test. Another way is via the developer console. And also a third way is via Ides like the Vs code IDE. Now, what is an Apex unit test? An Apex Unit Test is a method that is contained in classes called Test Class, which are specifically created for that purpose. These methods don’t commit any data to the database and don’t send any emails, are always flagged with the keyword test method or the annotation.

At is test at the method definition level and must always be defined in a test class. And this test class should be annotated with the at istest annotation and are always defined as static methods and take no arguments. This is an example. The class my test class is the test class which is annotated with the addis test annotation status methods can be created with either of these two syntaxes the test method keyword or the ad is test annotation. So as you can see, we have two test classes with the same name. Both of these test classes are annotated with the Ad is test annotation. So this will say that this class is a test class. Now, the methods of this class must be annotated with either the at is test annotation or they must be marked with the test method keyword after the static word. So both of these two test classes are exactly the same.

Mainly, this is the new annotation and this is the older one. Until now, we have just covered the Apex code coverage with testing. We still did not compare the actual result with the expected result. It’s very important to test for different inputs to ensure the quality of your code. For that, we can use something called System that Assert Methods. What are the system that assert methods? Well, there are three assert methods in the system class. The first one is the System that Assert method. This method takes one required argument and another optional argument. The required argument is the condition itself. And this method will assert if the condition is true. If it’s not true, an error will be returned that causes code execution to hold. The optional parameter is the error message that you can specify. The second one is the System that assert equals method that takes two required arguments and one optional argument.

The first required argument or parameter is the expected result and the second is the actual result. This method will assert if the expected and the actual arguments are the same and if not, an error will be returned that causes code execution to hold. The optional parameter is the error message that you can specify. The third method is called system that assert not equals. This method is the opposite of the system that assert equals method. So the job of this method is to assert that the expected and the actual arguments are not the same. The system assert methods are used to verify as many possible scenarios and use cases as possible. They can be used for both positive test cases and negative test cases. Other methods that can be used within test classes are the tests that start test and the Test that stop test system methods.

 These methods will separate the governor limits and will give a new French governor limit set right before test execution. Let’s see them in detail. The test that start test method marks the point in your code when your test begins. Test that Start test is used in conjunction with the Stop test method. Each test method is allowed to call it only once. After you call this method, you get a fresh set of governor limits for the remainder of the test until you call test that stop test and code before. This method should be used to initialize variables, populate data structure and so on. The test that Stop test method marks the point in your code when your test ends is used in conjunction with the Start test method and each test method is allowed to call it only once. Another method that can be used within test classes is the system that Run as method. The system that Run as method enables you to write test methods that change the user context to an existing user or to a new user so that the user’s record sharing is enforced. The main use of the Run as method is to test if a specific user has access to specific records. This is because the Run as method does not enforce user permissions or feed level permission, it only enforces record sharing.

You can use Run as only and test methods and the original system context is started again. After all, Run as test methods are complete. And finally, the Run as method ignores user license limits and you can create a new users with Runas even if your has no additional user licenses. This is a test class example that contains a test method that uses the system that Run as method. As you can see, the code in red is running using the user U that was created earlier in the test method. So if we run the system debug that shows the current user name and another system that debug that shows the profile, we get the info for this specific user. So as a summary, the Run as method makes any code within it run as the specified user and this only includes access to records and not permissions or field level security. So in this case and if you want to test if a user you does not have access to a specific record, you can use the run as method. Now, let’s create an Apex class that is used to create share records for the invoice object.

As you can see, we have a class called invoice sharing. And within this class we have a method called Manual share read. This method takes two parameters ID record ID and ID user or group ID. What does this method do? First of all it will initiate a new record of the object envoy share. So envshr is initiated and it’s a new instance of the embossare object.

And then we have the different fields of this record. We have specified the parent ID to be the record ID that is taken from the parameter. We have specified the user or group ID to be the user or group ID taken from the parameter. We have specified the access level to be read. And then we have specified the row calls to be this. So in this case the row calls will be Apex underscore underscore C which is a custom reason created in the classic user interface.

And then at the end we are inserting this record. So basically this method will create one share record that will share a record with the ID record ID with this ID which is the user or group ID. And the type of this share or the axis is read and the row code is Apex underscore underscore C. So it’s a very simple method that will simply create a record and the share object. Now, this is the equivalent test class that I have created to cover the invoice sharing class. As you can see, we are annotating this class by the add is test annotation. So this will specify that the invoice sharing test is indeed a test class. And then we have a method called test manual share read. And this is a unit test. Why? Because we are also using the add is test annotation. We can also use the test method keyword.

So what does this method do? First of all it will get three users from the. So as you can see, we have this so called query and then we have limit three. So which means that this list of user which is called Users will get three users. The first one is called users Zero. And then we are taking the idea of this first one and then we are putting it in this variable and we are doing the same for the other two users. Now we are creating a new invoice. We are specifying the description of this to be n one and then the owner of this invoice is this ID. So which is the first user’s ID. And then we are inserting the invoice record and then we are invoking the test that start test which will give us a new set of governor limits. And then what we are doing, we are calling this method from this class. So this is basically this method from the invoice sharing class and we are calling it after having a fresh set of governor limits and we are passing it two parameters. The first one is the invoice ID which is the ID of the invoice that we have inserted and the second one is the user one ID which is the ID of the second user.

So what does this do? It simply add this user on the invoice share table or object. It will add it as a read access user. So in this case user one can now read this invoice and then after adding this invoice Share record we are taking it so you can see that we have a so called query. And this so called query is having these fields like I’m taking ID, user or group ID access level and row codes from invoke share where parent ID equal to NF ID and user or group ID equal to user one ID.

So this will take the share record that we have just inserted. So the first assertion is to check if indeed we have size equal to one on the IMF shares list. If it’s not equal to one we will get this error message. And then the second assertions are what we are asserting. If first of all the Share record has access level to read and this Share record has row codes equals to apex underscore underscore C and this Share record has user or group ID equal to user oneID. So this is the second set of assertions.

And then the third set of assertions is what is running as user zero, users one and users two. So these are what let me go back and as you can see here, I have this list of users. The first one is the owner of the invoice record. The second one is the user that we have shared the invoice record with and the third one is a user that should not have access to the invoice. So if I go back to the run as methods you can see that now I am running as the owner.

So if I am the owner and then I have this so called query that will get me the count of the records and the invoice object. This count will be put in this variable and then I’m using the system that assert equals to C. So in this case, because this is the owner, the owner should only have access to one record. So the number of invoice records that the owner can see is equal to one. And then now we are running as users one which is the one that we have shared the invoice record with and then we are doing the same thing.

So because this has been shared with this user. This user should be able to have access to only one inbox record, which is the one that was shared with him. And the third assertion is for users too, which is the third user. So this user, because he or she does not have access to the invoice record, the number of invoice records should be zero. Now let’s go to salesforce to see unit test for Apex sharing in action. So as you can see, this is the invoice sharing class and as you can see we have this method that will share this ID with this user. So now let’s go to the itself and let’s check this emboss.

So I have invoice one. So emboss one is owned by me. So what I will do first I will check the share table of the emboss object to see which user can access it. So for that let’s go to the workbench. So, as you can see now we have this share table which has these six records. So if I click on this one, you can see this is myself as the owner and this is the owner of another invoice and so on. So if I click on let’s say this one. So we have parent ID BCBM. So we have these two are the same.

So let’s see the other user that can access this invoice one. So it’s Angela. So what we’ll do now, so this invoice one can be accessed by myself and by Angela. What I will do, let me go to the users and let’s search for another user. So let’s say that we want to share this with Sarah. So let me get the idea of Sara and let’s go to the developer console control e and let’s call this method so it will be invoice. Let me first put the ID and I will do this. So this will be the ID of the user and the ID of the record is this one. So let’s invoke this oh, I need to put so now if I go back to the workbench and I query this again, you can see that now we have this why we have this because if I go back to the class you can see that I have this as the reason. So now this record can be read by Sarah.

Now, if I go back to the developer console and then if I open the test class and if I run this, you can see that this will invoke this method. So to run this test class I just need to click on the run test and I can click on tests to see if this succeeded or not. Now, to be able to see which lines were covered in the class, I can go to the class itself and then I can click on this to check the coverage. So you can see that everything in blue is covered by test classes. So in this case it is covered by this test class. Now, what happens if let’s say I take this method control C, and then I paste it, and then I change it to edit, and then I make this access to be Edit. So what I did, I just added another method under this class, but this time it will add a record and this record will have access level equals to edit. So it’s exactly the same as this one. But now we are giving edit level instead edit axis instead of read access. So let’s save this control S and let’s run this test class again.

So this will run the unit test, which is one test. And then now if I go back to this and then if I check the coverage, you can see that only the first method is covered, not the second one. Why? Because this unit test only invokes this method. So the fact that this method is being invoked means that this unit test goes to this class and then runs this. By running this, all of these lines will run, but this will not run. Why? Because it’s not being called from this test class. To be able to cover this, we have to specify another line that will also run this method. And that’s it for this lecture. In this lecture, we have talked about testing in general and why it is needed. It is a very important step to check the configurations that were made in Apex. Unit test are class methods that verify whether a piece of code is working properly. In other words, it is Apex code that tests another Apex code.

We mentioned that in salesforce, Apex cannot be directly added to a production environment, but it should be first added to a sandbox and then it should be deployed to a production environment. In order for your Apex code to be deployed to a production environment, 75% of the whole Apex lines of code should be covered by unit tests. This is the total of lines of code. And also each unit test must pass. So any assertion that you add to unit tests must not fail. And finally, each trigger must have some test coverage. So at least one line of code, any trigger must be covered by unit tests. To be able to write unit tests, these methods should belong to a class that is annotated with the add is test annotation. And each unit test must also be annotated with the add is test annotation or with the test methods keyword. We talked about the different methods that can be used with unit tests.

And these are system assert methods that are used to check the class output as opposed to only performing code coverage. Test that start test and test that stop, test that will give a new fresh governor limit set right before test execution and system that run as that changes the current user to the specified user and executes the test as. This user and this system that run as will force force the sharing. It will force the access to the records. So if, let’s say we are running as a user that doesn’t have access to specific records, the system that runs will enforce this, but it will not enforce feed level security and permissions. And finally, as usual, thanks for watching.