function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Roger WickiRoger Wicki 

runAs() query user object

Dear Community

I have a couple of apex handler classes which are executed on certain trigger actions. It so comes that the test classes of the individual apex classes do interfere with one another.

So I might have some code executed on an OpportunityLineItem insertion which updates the Opportunity. For the test class i need to create an test opportunity record which will also cause all my triggers on opportunity to run.

All of this is no problem yet. But here it comes: One of my Test classes uses the "System.runAs()" with different users to create test opportunities because depending on the user/profile/permission set assigned to the user, some code might execute differently.
Because this runAs method will create opportunities as different users and I have a trigger on Opportunity which executes a SOQL on the User object, the SOQL itself is executed as the user defined in the runAs method. Now for some unclear reason, I receive an error that there was no record to assign to a variable (see example)
User aUser = [ SELECT Id FROM User WHERE isActive = true AND Profile.Name = 'System Administrator' LIMIT 1 ];

Every user / profile associated with user which could possibly run this query has at least read access to the user object (sharing rules). I don't know if they have default access to the Profile object, but if that would be the problem, I'd expect another error message. The one I receive is the following:

System.QueryException: List has no rows for assignment to SObject

I'd expect an insufficient cross-object access error if Profile.Name would not be available...

Do you have insights on that?

Best Answer chosen by Roger Wicki
ManojjenaManojjena
Hi Roger ,

Please use like this it will not throw you MIX_DML_Operation Error .
 
@isTest
                    
private class TestRunAs {
   public static testMethod void testRunAs() {
      // Setup test data
      // This code runs as the system user
      Profile p = [SELECT Id FROM Profile WHERE Name='Standard User']; 
      User u = new User(Alias = 'standt', Email='standarduser@testorg.com', 
      EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US', 
      LocaleSidKey='en_US', ProfileId = p.Id, 
      TimeZoneSidKey='America/Los_Angeles', UserName='standarduser@testorg.com');

      System.runAs(u) {
         // The following code runs as user 'u' 
         System.debug('Current User: ' + UserInfo.getUserName());
         System.debug('Current Profile: ' + UserInfo.getProfileId()); 
      }
   }
}

 

All Answers

Surendra nuneSurendra nune
Rather than querying the user, can u try creating the user and run tests as shown below:

 public static User createUser(String profileName){
        Profile profile = [select id from Profile where Name =:profileName limit 1];
        string uName;
        if(profileName.equalsIgnorecase(PP_Constants.WAREHOUSE_MANAGER_PROFILE_NAME)){
            uName = 'whmgr@testorg.com';
        }else if(profileName.equalsIgnorecase(PP_Constants.SALES_REP_PROFILE_NAME)){
            uName = 'salesrep@testorg.com';
        }
        User userObj = new User(Alias = 'dev501', Email='dev501cert@testorg.com', 
        EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US', 
        LocaleSidKey='en_US', ProfileId = profile.Id, 
        TimeZoneSidKey='America/Los_Angeles', UserName=uName);
        return userObj;
    }
ManojjenaManojjena
Hi Roger ,

I think below link have some code it will solve your problem .Instead of query from User you can query from profile and create usser record and use that in runAs ().

Please check and let me know any issue .

https://www.salesforce.com/us/developer/docs/apexcode/Content/apex_testing_tools_runas.htm
Roger WickiRoger Wicki
I will not be able to create the user because in the same context there are non-system objects created. This will lead to an error.

Unless your suggestions work without actually having to insert the user...
Surendra nuneSurendra nune
Could you please elaborate on what will lead to error?
 
Roger WickiRoger Wicki

I'm referring to this article:
https://www.salesforce.com/us/developer/docs/apexcode/Content/apex_dml_non_mix_sobjects.htm

I don't know the exact phrasing of the error message.

ManojjenaManojjena
Hi Roger ,

Please use like this it will not throw you MIX_DML_Operation Error .
 
@isTest
                    
private class TestRunAs {
   public static testMethod void testRunAs() {
      // Setup test data
      // This code runs as the system user
      Profile p = [SELECT Id FROM Profile WHERE Name='Standard User']; 
      User u = new User(Alias = 'standt', Email='standarduser@testorg.com', 
      EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US', 
      LocaleSidKey='en_US', ProfileId = p.Id, 
      TimeZoneSidKey='America/Los_Angeles', UserName='standarduser@testorg.com');

      System.runAs(u) {
         // The following code runs as user 'u' 
         System.debug('Current User: ' + UserInfo.getUserName());
         System.debug('Current Profile: ' + UserInfo.getProfileId()); 
      }
   }
}

 
This was selected as the best answer
Roger WickiRoger Wicki
Thanks, I'll give this a try after lunch. I just hope I will be able to query for the Profile being in the runAs method......
Roger WickiRoger Wicki
It kind of works... for the first time this code piece runs through. But because all test classes together make this particular piece of code to be executed 20 times, I get 19 DUPLICATE_USERNAME exceptions.

I think I'm going to create a static god user with admin rights and then let him run this piece of code every time.
Surendra nuneSurendra nune
generate dynamic username like 

Username = Datetime.now().getTime() + 'x@y.com'
Surendra nuneSurendra nune
Please mark it as solved.
Roger WickiRoger Wicki
Hmm, I didn't even think about that :D

Yeah would be a got to but it seems my static user works just fine. I use some sort of a constructor class anyway for my most used objects, ehich includes users. I just expanded it by a static user variable for the admin and a static function to create it...

Thanks