-1

I'am working on Test class it has code coverage as well. I used system.assertEquals statements,But anyone can please help me to use better system.assertmethods in below scenario with Proper explanation

Still I think that I can Improve this Test class with system assert methods

I have this trigger:

 trigger AssignPermissionSet on User (after insert,after Update) {
PermissionSet pereset = [SELECT Id FROM PermissionSet WHERE Label ='SBU Impact Visible'];
Set<ID> addIds = new Set<Id>(),
        removeIds = new Set<Id>(),
        roleIds = new Map<Id, UserRole>([
    SELECT  Id FROM UserRole 
    WHERE   Name LIKE '%E&C%' OR Name LIKE '%Commerical Ops%' OR Name LIKE 
 '%Energy & Chemicals%' OR Name LIKE '%All Fluor%'
    OR Name LIKE '%System Administrator%'
]).keySet();
for(User record: Trigger.new) {
    (record.IsActive && roleIds.contains(record.UserRoleId)? addIds: removeIds).add(record.Id);
}
  PermissionSetAssignment[] permissionSetList = new PermissionSetAssignment[0];
addIds.removeAll(new Map<Id, AggregateResult>([SELECT AssigneeId Id FROM PermissionSetAssignment 
   WHERE AssigneeId = :addIds AND PermissionSetId = :pereset.Id GROUP BY AssigneeId]).keySet());

for(Id userId: addIds) {
    permissionSetList.add(new PermissionSetAssignment(PermissionSetId = pereset.id, AssigneeId = userId));
}
upsert permissionSetList;
delete [SELECT Id FROM PermissionSetAssignment WHERE AssigneeId =:removeIds AND PermissionSetId =:pereset.Id];

}


I have this Test class:

@isTest
public class Test_AssignPermissionSet {
public static testmethod void userTest(){
    // This code runs as the Standard User
    Profile profileId = [SELECT Id FROM Profile WHERE Name = 'Standard User' LIMIT 1]; 
    //User role creation
    UserRole r = new UserRole(DeveloperName = 'MyCustomRole', Name ='System Administrator');
    insert r;
    // Perform user data preparation.
    User usr = new User(LastName = 'TestAssignmentUser',
                        FirstName='TestAssignUser',
                        Alias = 'Test',
                        Email = 'Test@gmail.com',
                        Username = 'testAssign@gmail.com',
                        ProfileId = profileId.id,
                        TimeZoneSidKey = 'GMT',
                        LanguageLocaleKey = 'en_US',
                        EmailEncodingKey = 'UTF-8',
                        LocaleSidKey = 'en_US',
                        UserRoleId = r.Id
                       );
    // Start the test, this changes governor limit context to
    test.startTest();
    // Insert the user records that cause the trigger to execute.
    insert usr;
    PermissionSetAssignment per=[select PermissionSetId,PermissionSet.Name,PermissionSet.label,AssigneeId from PermissionSetAssignment where Assignee.Id =:usr.id limit 1];
    // Comparing Permission set userId with Inserted UserId
    // This indicates Permission set created for that Inserted User
    system.assertEquals(usr.Id,per.AssigneeId);
    PermissionSet permission=[SELECT Name,Label FROM PermissionSet where id=:per.PermissionSetId];
    system.assertEquals('SBU Impact Visible',permission.Label);
    // Stop the test, this changes limit context back to test from trigger.
    test.stopTest();
}}
6

Well, my first advice is... make code readable. Sure, you optimized the amount of lines written, but it took me 5 minutes to understand a trigger that was around 25 lines long with no nested loops or complex behaviour.

I've tried to tweak it as little as possible, but I think the following is much more dev-friendly. Things like indentation, spaces and naming help a lot. Take it into account, specially when posting online for others to read.

trigger AssignPermissionSet on User (after insert, after Update) {
    PermissionSet pereset = [SELECT Id FROM PermissionSet WHERE Label ='SBU Impact Visible'];

    Set<Id> addIds = new Set<Id>();
    Set<Id> removeIds = new Set<Id>();
    Set<Id> roleIds = new Map<Id, UserRole>([
        SELECT Id 
        FROM UserRole 
        WHERE Name LIKE '%E&C%' OR Name LIKE '%Commerical Ops%' OR Name LIKE '%Energy & Chemicals%' OR Name LIKE '%All Fluor%'OR Name LIKE '%System Administrator%'
    ]).keySet();

    for(User record : Trigger.new) {
        if(record.IsActive && roleIds.contains(record.UserRoleId)) {
            addIds.add(record.Id):
        } 
        else {
            removeIds.add(record.Id):
        }
    }

    PermissionSetAssignment[] permissionSetList = new PermissionSetAssignment[0];
    addIds.removeAll(new Map<Id, AggregateResult>([SELECT AssigneeId Id FROM PermissionSetAssignment WHERE AssigneeId = :addIds AND PermissionSetId = :pereset.Id GROUP BY AssigneeId]).keySet());

    for(Id userId: addIds) {
        permissionSetList.add(new PermissionSetAssignment(PermissionSetId = pereset.id, AssigneeId = userId));
    }

    upsert permissionSetList;

    delete [SELECT Id FROM PermissionSetAssignment WHERE AssigneeId =:removeIds AND PermissionSetId =:pereset.Id];
}

Having said that, I understand your question as wanting minor improvement tips regarding the Test.

  1. Don't overcomment. Everyone knows that Test.startTest changes the context, so not commenting makes the code, again, more readable.

  2. You want to test the results post-execution of the trigger, therefore it does not make sense to include the asserts in between the Test.startTest and Test.StopTest. Have them afterwards. In this specific case, it doesn't matter, but on other ocassions it might, specially if your trigger throws async Apex.

  3. Make more tests. You're only covering one scenario. You can also test the scenario in which the User does not have a role, or when the role is not one hard-coded in the trigger, etc.

  4. To further improve your tests, readability, etc. You can consider using @TestSetup. In your case it could be interesting in order to insert the UserRole. Or not. Just take it into account down the road as another tool in your toolbelt.

  5. Prefer using @IsTest vs testMethod, since the latter is deprecated.

  6. Lastly, name your test methods appropiately indicating the use case. That serves as documentation too and helps fellow team mates work with you.

Here is an example of how I would have done it.

@IsTest
public class Test_AssignPermissionSet {

    @IsTest
    public static void when_user_is_inserted_then_assign_permission_set(){
        Profile profileId = [SELECT Id FROM Profile WHERE Name = 'Standard User' LIMIT 1]; 
        UserRole r = new UserRole(DeveloperName = 'MyCustomRole', Name ='System Administrator');
        insert r;

        User usr = new User(LastName = 'TestAssignmentUser',
                            FirstName='TestAssignUser',
                            Alias = 'Test',
                            Email = 'Test@gmail.com',
                            Username = 'testAssign@gmail.com',
                            ProfileId = profileId.id,
                            TimeZoneSidKey = 'GMT',
                            LanguageLocaleKey = 'en_US',
                            EmailEncodingKey = 'UTF-8',
                            LocaleSidKey = 'en_US',
                            UserRoleId = r.Id
                        );

        Test.startTest();
        insert usr;
        Test.stopTest();

        // Comparing Permission set userId with Inserted UserI. This indicates Permission set created for that Inserted User
        PermissionSetAssignment per = [SELECT PermissionSetId, PermissionSet.Name, PermissionSet.label, AssigneeId FROM PermissionSetAssignment WHERE Assignee.Id = :usr.id LIMIT 1];
        PermissionSet permission = [SELECT Name, Label FROM PermissionSet WHERE Id = :per.PermissionSetId];
        System.assertEquals(usr.Id,per.AssigneeId);
        System.assertEquals('SBU Impact Visible',permission.Label);
    }
  • Thank Javier :) – Annappa PH Aug 1 '18 at 10:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.