+ Start a Discussion
J KeenerJ Keener 

Simulating Different Users performing updates in a Trigger's test method

I've built a simple trigger that will stop an update to a record based on a user's profile.  In building a test method for this trigger, I don't see any way to simulate both sides of the processing, since the logic in the trigger is dependant on the results of the getUserInfo calls. 
 
The issue, is how to get to 100% code coverage in a test method in this sort of situation?
 
What I'd like to be able to do in my test method is the following:
 
using my current admin login,
update 200 records  (These would succeed, as the admin profile is allowed to make the updates)
 
switch login to a non-admin user login
update 200 records (These would not succeed, and the addError would be applied to the appropriate fields)
 
Jon Keener
 
jeremyfrey1jeremyfrey1
Have you tried to abstract the "are you authorized" code away from the trigger?  Try making a class with a function that returns true if the user is authorized, and false if the user is not authorized.  The test method for this class could then call the function with both privileged and non-privileged profile IDs.
J KeenerJ Keener

That is something that we are already doing, and already have 100% coverage of the code in the APEX class.

The challenge is specifically the code in the trigger, when the call returns true or when the call returns false.

Specifically in this trigger, it's when it returns false, which will never happen with my login.  The call to the checkUserRights() function uses the getUserInfo object to retrieve current user information.  The logic in the routine determines the current users profile, compares it to a valid list of profiles, and if it is in the list, returns true, otherwise, it returns false.

What I would want to be able to do is build a test method that would perform updates as me, then allow me to somehow act as a different user so that when checkUserRights called the getUserInfo object, it would return a different users info.

One item I attempted unsuccessfully was changing the profile of the current user in the test method.  However, the update to the profile was not picked up by the getUserInfo object, as it still reflected to original profile.  (I thought this might have been the way to do it, since the profile change would not have persisted after the test method)

below is the snippet of code I added to my test method to change my profile id temporarily during processing.  Basically, my intent was to perform an update prior to this code, that would hit the true logic in the trigger (which allows the updates to occur), and then a second set of updates after this code was ran, that would then generate a false result in the trigger that would test the false branch, and peform the error portion of the trigger.  Unfortunately, the AssertEquals fails, which shows that the getUserInfo object isn't refreshed in the middle of processing.

Code:
User user = [SELECT Id, FirstName, LastName, ProfileId FROM User WHERE Id = :UserInfo.getUserId()];

user.ProfileId = [SELECT Id FROM Profile WHERE Name = 'Sales Representative'].Id;
update user;

System.assertEquals(UserInfo.getProfileId(),user.ProfileId);


 

Jon Keener

 

Code:
trigger checkMaterialNameNoChange on CIS_Materials__c (before update) {

   // a trigger to ensure that the Material Name field has not changed while in edit mode
   // The following line calls an Apex Class which checks whether the user is allowed to change the name of a Material

   if (!VerifyUserNameChangeRights.checkUserRights())  {
      for (Integer i = 0; i < Trigger.new.size(); i++) {
         if (Trigger.old[i].Name != Trigger.new[i].Name) {
            Trigger.new[i].Name = Trigger.old[i].Name;
            Trigger.new[i].Name.addError('You cannot change the name of the material.');
         }
      }
   }
}


 



Message Edited by J Keener on 05-14-2008 01:02 PM
TehNrdTehNrd
If that is the only thing you are doing with this trigger what about using a validation rule instead?

You could use the functions:
ISCHANGED()
$User.ProfileId
ppatppat
Jon Keener ,

Are you able to find the solution ? I have exact same situation and running into the same issue of not being able to change the profiles in test method.

Please reply back as no documentation can be found on this. I am using this in the trigger and not in visualforce.

Thanks in advance for help.

-Pramod
J KeenerJ Keener
No,  I have not been able to find a solution for this type of testing yet. 
 
 I was able to get my trigger above working as a Validation Rule, as one person previously mentioned, which helped.  I am developing some more triggers where this will still be an issue though.
 
Jon Keener
ppatppat
Thanks Jon .. Please let me know if you find the solution. I will try to escalate with support.

I am just surprised that no one from saleforce have commented on this yet as what is the right way of doing this type of testing for all userinfo. mehods . Examples would be great.

-Pramod
CrustyCrusty

This seems like an old post, but using RunAs in a test method allows the user context to be switched to another profile.

http://wiki.developerforce.com/index.php/An_Introduction_to_Apex_Code_Test_Methods