2

I'm writing a Test Class in order to test some code which automatically completes CaseMilestones when certain changes are made to a Case.

My code checks that the Case which has been changed has a Record Type Id that's included in my Custom Setting. In my Test Class, I need to create the Custom Setting and also create the CaseMilestones, Account, Entitlement, Opportunity etc. which the Case that I update in the Test Class will be related to.

As soon as the test get's to the line insert msList; it causes the test to fail, with the error stating that the combination of the Custom Setting & Milestone caused the Mixed DML Operation error.

I've found plenty for explanations of this error & solutions but in every example that I've seen, the assumption is that the purpose of the code is to Insert the Setup Object which means that a @future class can be written & referenced in the Test Class, see the Salesforce documentation, for example.

My Custom Setting already exists and doesn't need to be inserted again in Production so I'm not sure how to resolve this issue.

@isTest
private class completeCaseMilestone_Test {

    static testMethod void testCaseMilestone(){

        WEID__c[] csList = new WEID__c[]{};
            WEID__c cs = New WEID__c();

        cs.Name = 'WE Application';
        cs.WECaseId__c = '012700000005x2r';
        csList.add(cs);

        insert csList;
        system.debug('csList contains ' + csList);

        List <MilestoneType> msList = new List <MilestoneType>();

        MilestoneType m1 = new MilestoneType();
        m1.Name = 'Case Accepted';
        msList.add(m1);

        MilestoneType m2 = new MilestoneType();
        m2.Name = 'Create & CSDM Approve Account';
        msList.add(m2);

        insert msList;

        User u = new User();

        u.FirstName = 'A';
        u.LastName = 'S';
        u.Email = '[email protected]';
        u.Username = '[email protected]';
        u.Alias = 'astest';
        u.ProfileId = p1.Id;
        u.TimeZoneSidKey    = 'America/Denver';
        u.LocaleSidKey      = 'en_US';
        u.EmailEncodingKey  = 'UTF-8';
        u.LanguageLocaleKey = 'en_US';

        insert u;
        system.debug('u contains ' + u);

        // create Account, Entitlement, Opportunity etc.

        Case c = new Case();

        c.OwnerId = u.id;
        c.Status = 'Application Submitted';
        c.Subject = 'Test Submit Application';

        c.RecordTypeId = '012700000005x2r';
        c.Subject = 'New Application';
        c.EntitlementId = ent.Id;
        c.Opportunity__c = o.Id;
        c.AccountId = a.Id;

        insert c;

        List<Case> cToUpdate = [SELECT Id, OwnerId, Status FROM Case
                                WHERE Subject = 'Test Submit Application'];

        system.debug('cToUpdate contains ' + cToUpdate);

        for (Case case1 : cToUpdate){
            c.OwnerId = u.id;
        }
        update cToUpdate;

    }
}

1 Answer 1

0

Usually this error occurs when you insert data in both regular objects and setup objects in the same transaction. Best way to overcome this error is to insert a user and other setup objects in test class and use System.runAs(). Check the link below,

https://developer.salesforce.com/page/Apex_Testing_with_RunAs

UPDATE - Insertion of user cannot be done with other transactions. Insert user first and then put all other code inside

System.runas(u){
    //test coverage code here.
}

EXAMPLE

@isTest
private class completeCaseMilestone_Test {

    static testMethod void testCaseMilestone(){

        Profile p1 = [SELECT Id FROM Profile WHERE Name = 'System Administrator - Test'];

        // create User
        User u = new User();

        u.FirstName = 'A';
        u.LastName = 'S';
        u.Email = '[email protected]';
        u.Username = '[email protected]';
        u.Alias = 'astest';
        u.ProfileId = p1.Id;
        u.TimeZoneSidKey    = 'America/Denver';
        u.LocaleSidKey      = 'en_US';
        u.EmailEncodingKey  = 'UTF-8';
        u.LanguageLocaleKey = 'en_US';

        insert u;
        system.debug('u contains ' + u);

        System.runas(u){

            // create non-setup records & run tests here
        }
    }
}
4
  • Thanks so to clarify, I create the Custom Setting and the User, then runAs and create the remaining records and do the testing?
    – Alex S
    May 27, 2015 at 16:26
  • I have updated answer. Please check
    – Victor
    May 27, 2015 at 16:29
  • I'm still not completely sure how this solution will work but I'll have a go and let you know whether it works.
    – Alex S
    May 27, 2015 at 16:30
  • system.runas(u) will simulate execution as the different user u
    – Victor
    May 27, 2015 at 16:32

You must log in to answer this question.

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