+ Start a Discussion
garybgaryb 

Testing code reliant on configuration - MIXED_DML_OPERATION woes!

Hi all,

 

I have some code that looks at CaseTeamTemplates and behaves differently depending on those CaseTeamTemplates. I'm trying to test the code but to do that I need to insert some CTTs. However, I can't do that and then insert, for example, Cases as I get a MIXED_DML_OPERATION error - basically, I can't insert setup objects and non-setup objects in the same test. So.... how can I give my code the necessary test coverage?

 

Anybody encountered this before and managed to work around it?

Best Answer chosen by Admin (Salesforce Developers) 
WesNolte__cWesNolte__c

All Answers

WesNolte__cWesNolte__c
This was selected as the best answer
garybgaryb

Wez, thanks for the response, however I'm aware of that issue already and unfortunately it won't help my situation.

 

Let me present the problem in a completely different format to demonstrate:

 

I have a trigger on the User object that is interested in Customer Portal users and creates CaseTeamTemplates. To test the trigger I need to create customer portal users; to create customer portal users, I need to create accounts and (for non-person accounts) contacts. When I insert the user however, that creates CaseTeamTemplates and bam, Mixed_DML_Operation errors!

 

These processes are separate in day-to-day use so this isn't a problem IRL. But to _test_ the trigger, I effectively need to do both in one transaction (or rely on data in the database which I just don't think I can bring myself to do). Does that make sense?

WesNolte__cWesNolte__c

Yeah it makes sense. So what is order of DML? Is it:

 

1. Insert account and contacts

2. Insert Users

3. Trigger creates CaseTeamTemplates

 

If this is correct and working in your production environment I assume the records in 3 are created in a @future method? If this is the case then you should still be able to apply the workaround. Let me know if I've misunderstood.

 

Wes

garybgaryb

Unfortunately the tests aren't in production and working. I have enough coverage to get them into production, but they're not being tested. Also, the records aren't created in an @future method. I guess I could wrap them in a future method but I don't see any reason to other than to get the testing working...

osamanosaman

There is a work around for that.

If you want to perform two DML operations sequentially, create a seprate method for 2nd DML operation with @future token.

make sure you put System.RunAs() in the method. Your overall method should look like this

 

private static void myFunc()

{

     ///1st DML operation

 

     User usr = [Select id from User where Id = :UserInfo.getUserId()];

 

     System.RunAs(usr)

     {

        Test.startTest();

         myFunc2();

         Test.stopTest();

     }

 

 

}

 

@future

private static void myFunc2()

{

   ///2nd DML operation

}

garybgaryb

Embarassingly, I misunderstood some of the advice I was pointed towards and provided with...

 

You can use System.runAs() to get round these problems. I thought this was a red herring as I was creating a user, but not to run something as that user, which a lot of the advice I found through searches was about.

 

The answer was along the lines of the stackoverflow link that Wez posted. To recap: I have a trigger that, when a user is created, it creates a CaseTeamTemplate and CaseTeamTemplateMember. To do that in a test, i need an Account and Contact first.

 

In the end, I inserted the account/contact objects in the test as normal, created the new Users (but did not insert them), then pulled out my User, then run the inserts in a System.runAs() with that User.

 

Thanks for all the help and suggestions, I got there in the end - will try harder next time :)