2
public with sharing class Utils_SDF_Methodology {
.
.
.
    public static final String BypassVar;//List of triggers that can be bypassed

    static{
        System.Debug('## >>> Utils_SDF_Methodology constructor :BEGIN <<< run by ' + UserInfo.getName());
        User user=[SELECT UserRole.Name,Profile.Name,BypassTriggers__c FROM User WHERE Id =:UserInfo.getUserId() LIMIT 1];
        BypassVar=';'+user.BypassTriggers__c+';';
        System.Debug('## >>> Utils_SDF_Methodology constructor : END <<<');
    }
.
.
.
}

I have to write a Test Class in which I have to user runAs(userX){ inside of which I want static init block of above class should run.}

I have created below code in my TEST method:

User LCRTestUser = Utils_TestMethods.createStandardUser('LCROwner');
    LCRTestUser.BypassTriggers__c = 'AP33;AP20;AP_Case_CaseHandlerCaseBeforeInsert;AP10;AP41'; 
    System.debug('LCRTestUser.BypassTriggers__c:'+LCRTestUser.BypassTriggers__c);
    //Insert LCRTestUser ;
    System.debug('UserInfo.getName():'+UserInfo.getName());
system.runas(LCRTestUser) {
    Test.startTest();
    System.debug('runAs Started');
// Test.startTest();
     System.debug('UserInfo.getName():'+UserInfo.getName());


 System.debug('Utils_SDF_Methodology.PAD_BypassTrigger:'+Utils_SDF_Methodology.PAD_BypassTrigger);

Test.stopTest();

But still it is initializing with main user, Not the user which is in runAs(). System.debug('UserInfo.getName():'+UserInfo.getName()); in TEST method is providing name of the user who is in runAs. Static init block is executing after runAs but before this debug and is considering actual user.

Can I do anything so that it will consider user mentioned in runAs in static initialization block?

2 Answers 2

3

Why do you need to make the method creating the user static? What I normally do when testing with different user, I write in a base test class which is virtual so you can inherit in the test method and in there you have some lazy initialization like this:

public virtual class SF_BaseTest {  
           public static SF_BaseTest t;
           /** a default user to use in System.runAs() */
           public User adminUser {
           get {
                if (null == adminUser) {
                // all test code should execute under a user we can control so as to avoid
               // surprises when deploying to different environments.
               UserRole[] roles = [SELECT Id FROM UserRole WHERE DeveloperName =  'System_Administrator'];
            if (roles.isEmpty()) {
              roles.add(new UserRole(DeveloperName = 'System_Administrator', Name = 'r0'));
              insert roles;
            }

            adminUser = newUser('[email protected]');
            adminUser.UserRoleId = roles[0].Id;
            insert adminUser;
          }
          return adminUser;
        }
        private set;
      }

  // Helpers
  private User newUser(String username, Id profileId) {
    return new User(
      ProfileId = [SELECT Id FROM Profile WHERE Id = :profileId LIMIT 1].Id,
      LastName = 'last',
      Email = '[email protected]',
      Username = username + System.currentTimeMillis(),
      CompanyName = 'sf',
      Title = 'title',
      Alias = 'alias',
      TimeZoneSidKey = 'America/Los_Angeles',
      EmailEncodingKey = 'UTF-8',  
      LanguageLocaleKey = 'en_US', 
      LocaleSidKey = 'en_US'
    );
  }}

And then in your test class:

class SF_Test extends SF_BaseTest {
      static testMethod void testEmail() {
            System.runAs(t.adminUser) {
                  test.startTest();
                  //Your test
                  test.stopTest();
            }
      //--------------------------------------------------------------------------
     // Helpers
     static { SF_BaseTest.t = new SF_Test(); }
     static SF_BaseTest t { get { return SF_BaseTest.t; } }
}

Also this SOQL query you have in your code

User user=[SELECT UserRole.Name,Profile.Name,BypassTriggers__c FROM User WHERE Id =:UserInfo.getUserId() LIMIT 1]; 

Will always select the admin user that will run the test because the method getUserId() in the UserInfo class will get the current user in the execution context.

In the code that I showed the user is created as part of the test data and then the user is being deleted once the unit test has finished.

Hope it helps.

1
  • This is a good approach, although does not answer how to run a static initializer as the test user. I want to do the same thing. Main reason is to not have to call a data-setup method from each test method's System.runAs(), but whatever, just minor duplication. May 10, 2015 at 14:37
0
private class TestClass {

    static User testUser;        

    static {
        testUser = someMethodCreatingTestUser();
        System.runAs(testUser) {
            // set up test data
        }
    }

    static TestMethod test() {
        System.runAs(testUser) {
            // run tests
        }
    }    
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .