0

My team uses a sandbox for user onboarding, so I wrote a SandboxPostCopy class to populate the training sandbox with sets of records and create test users on refresh. The class compiles and, as far as I can tell, everything runs as expected.

The problem is: My SandboxPostCopy class inserts records in the User object as well as other objects, so it throws a mixed DML exception unless the method updating users is annotated with @future, and I can't figure out how to write tests that cover this method. I've tried querying for the inserted users but queries don't turn up the expected data, especially when I'm looking at updated users.

Is there a specific way I should be approaching these tests? Do I need to put the user management stuff in a separate class?

Edit to add relevant code:

Here's the future method that updates users.

@future
private static void setupUsers() {
    List<User> train_users = new List<User>();
    Id profile_id = [SELECT Id FROM Profile WHERE Name = 'Case Managers' LIMIT 1].Id;
    Id role_id = [SELECT Id FROM UserRole WHERE DeveloperName = 'System_Administrator' LIMIT 1].Id;
    // get a random number to make sure usernames are unique
    String rand_num = String.valueOf(Math.random()).mid(3, 5);
    
    // Deactivate all active CMs
    List<User> user_deact = [SELECT Id, IsActive FROM User WHERE Profile.Name = 'Case Managers' AND IsActive = true];
    if (user_deact.size() > 0) {
        for (User u : user_deact) {
            u.IsActive = false;
        }
        update user_deact;
    }

    train_users.add(new User(FirstName='One', LastName='Training',
                            Alias='train1',
                            CommunityNickname='train1',
                            Username='trainingone@fakemail.fake.' + rand_num,
                            Email='email@fakemail.fake',
                            LocaleSidKey='en_US',
                            LanguageLocaleKey='en_US',
                            EmailEncodingKey='ISO-8859-1',
                            TimezoneSidKey='America/Los_Angeles',
                            UserPermissionsMarketingUser=true,
                            ProfileId=profile_id,
                            UserRoleId=role_id));
    train_users.add(new User(FirstName='Two', LastName='Training',
                            Alias='train2',
                            CommunityNickname='train2',
                            Username='trainingtwo@fakemail.fake.' + rand_num,
                            Email='email@fakemail.fake',
                            LocaleSidKey='en_US',
                            LanguageLocaleKey='en_US',
                            EmailEncodingKey='ISO-8859-1',
                            TimezoneSidKey='America/Los_Angeles',
                            UserPermissionsMarketingUser=true,
                            ProfileId=profile_id,
                            UserRoleId=role_id));
    train_users.add(new User(FirstName='Three', LastName='Training',
                            Alias='train3',
                            CommunityNickname='train3',
                            Username='trainingthree@fakemail.fake.' + rand_num,
                            Email='email@fakemail.fake',
                            LocaleSidKey='en_US',
                            LanguageLocaleKey='en_US',
                            EmailEncodingKey='ISO-8859-1',
                            TimezoneSidKey='America/Los_Angeles',
                            UserPermissionsMarketingUser=true,
                            ProfileId=profile_id,
                            UserRoleId=role_id));
    train_users.add(new User(FirstName='Four', LastName='Training',
                            Alias='train4',
                            CommunityNickname='train4',
                            Username='trainingfour@fakemail.fake.' + rand_num,
                            Email='email@fakemail.fake',
                            LocaleSidKey='en_US',
                            LanguageLocaleKey='en_US',
                            EmailEncodingKey='ISO-8859-1',
                            TimezoneSidKey='America/Los_Angeles',
                            UserPermissionsMarketingUser=true,
                            ProfileId=profile_id,
                            UserRoleId=role_id));
    train_users.add(new User(FirstName='Five', LastName='Training',
                            Alias='train5',
                            CommunityNickname='train5',
                            Username='trainingfive@fakemail.fake.' + rand_num,
                            Email='email@fakemail.fake',
                            LocaleSidKey='en_US',
                            LanguageLocaleKey='en_US',
                            EmailEncodingKey='ISO-8859-1',
                            TimezoneSidKey='America/Los_Angeles',
                            UserPermissionsMarketingUser=true,
                            ProfileId=profile_id,
                            UserRoleId=role_id));
    train_users.add(new User(FirstName='CM', LastName='Training',
                            Alias='traincm',
                            CommunityNickname='traincm',
                            Username='trainingcm@fakemail.fake.' + rand_num,
                            Email='email@fakemail.fake',
                            LocaleSidKey='en_US',
                            LanguageLocaleKey='en_US',
                            EmailEncodingKey='ISO-8859-1',
                            TimezoneSidKey='America/Los_Angeles',
                            UserPermissionsMarketingUser=true,
                            ProfileId=profile_id,
                            UserRoleId=role_id));

    insert train_users;
}

Here's the test class (without failing user query + asserts):

@isTest  
private class PopulateTrainingSandboxTest {  
    @isTest  
    static void testPopulateTrainingSandbox() {  

        Test.startTest();  

        Test.testSandboxPostCopyScript( new PopulateTrainingSandbox(), UserInfo.getOrganizationId(),
                                        UserInfo.getOrganizationId(), UserInfo.getOrganizationName() ); 
  
        Test.stopTest();

        List<Account> accounts = [select Id from Account];
        System.assertEquals(4, accounts.size());

        List<Contact> contacts = [select Id from Contact];
        System.assertEquals(11, contacts.size());

        List<Case> cases = [select Id from Case];
        System.assertEquals(4, cases.size());

        // New test statements to check for newly created test users
        // This block does not result in any code coverage for some reason.
        List<User> train_users = [select Id from User where LastName = 'Training'];
        System.assertEquals(6, train_users.size());
    }
}
5
  • 2
    I've successfully tested future methods called by SandboxPostCopy. Do you have code you could share in an edit? Do you have any logic/filtering in your class based on the sandbox name or anything like that? Sep 16 at 22:35
  • Hi @KrisGoncalves: Thanks for taking a look. I updated with code above. There's no logic that controls updates based on sandbox details. For the test class, I've tried to query updated users as well as created users with no success. Queries always seem to return results that suggest the future method didn't run, at least in the test context. Sep 16 at 23:33
  • What's the failing assertion and query? You can add try/catches in your code just to debug to see if anything is failing in the test context (in terms of deactivating/creating users). Sep 17 at 1:45
  • It's best to edit your question with updates as comments are hard to read if you want to share more code or extra info. Sep 17 at 18:16
  • @KrisGoncalves: Done. I edited the test class code with a block that queries for newly created training users. The new assertion passes, which means the @future method does run, but the new test statements don't count for test coverage unfortunately and I'm still not sure why. Thanks again for your feedback. Sep 17 at 19:09

Your Answer

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

Browse other questions tagged or ask your own question.