New Way to Avoid the Dreaded Mixed DMLError in Test Method

As of the Spring 16 release, there is now another way to avoid an error that would often occur when running Apex unit tests. The MIXED_DML_OPERATION error would occur because you can’t perform DML on a setup sObject (such as User, for example) and a non-setup object (such as Contact) in the same transaction.

So, if you had some code such as the following:


@isTest
public class UserAndContactTest {
    public testmethod static void testUserAndContact() {
        Profile p = [SELECT Id FROM Profile WHERE Name='Standard User'];
        UserRole r = [SELECT Id FROM UserRole WHERE Name='COO'];
        u = new User(alias = 'jsmith', email='jsmith@acme.com',
                emailencodingkey='UTF-8', lastname='Smith',
                languagelocalekey='en_US',
                localesidkey='en_US', profileid = p.Id, userroleid = r.Id,
                timezonesidkey='America/Los_Angeles',
                username='jsmith@acme.com');
            insert u;

        Contact currentContact = new Contact(
            firstName = String.valueOf(System.currentTimeMillis()),
            lastName = 'Contact');
        insert(currentContact);
    }
}

The unit test code above would fail with the MIXED_DML_OPERATION error.

Previously, the only way to get around it was to enclose all the operations within a System.runAs block, but now you have another alternative in which you can use @future to bypass the error. For example, the following class could contain the code used to insert the user:


public class InsertFutureUser {
    @future
    public static void insertUser() {
        Profile p = [SELECT Id FROM Profile WHERE Name='Standard User'];
        UserRole r = [SELECT Id FROM UserRole WHERE Name='COO'];
        User futureUser = new User(firstname = 'Future', lastname = 'User',
            alias = 'future', defaultgroupnotificationfrequency = 'N',
            digestfrequency = 'N', email = 'test@test.org',
            emailencodingkey = 'UTF-8', languagelocalekey='en_US', 
            localesidkey='en_US', profileid = p.Id, 
            timezonesidkey = 'America/Los_Angeles',
            username = 'futureuser@test.org',
            userpermissionsmarketinguser = false,
            userpermissionsofflineuser = false, userroleid = r.Id);
        insert(futureUser);
    }
}

And then, you could just change the original code to be the following:


@isTest
public class UserAndContactTest {
    public testmethod static void testUserAndContact() {
        InsertFutureUser.insertUser();

        Contact currentContact = new Contact(
            firstName = String.valueOf(System.currentTimeMillis()),
            lastName = 'Contact');
        insert(currentContact);
    }
}


And then there will be no more error. I think it is a better way of handling the issue than using runAs and should be considered when there is a need to run DML operations for setup and non-setup objects in the same unit test transaction.

Developing with Visualforce Course just went Live!!!

The Visualforce course I designed for Lynda.com, Developing with Visualforce just went live. You can access it here and even if you are not a member, you can view 4 videos for free.  DevlopingWithVisuaforce

I am pretty proud of the course. I spent a lot of time trying to think through the best way to teach this stuff to beginners. I hope that I succeeded in some small way. I would love to know what you think, good or bad. I don’t mind getting bad feedback because it helps me to get better.

This is just the beginning too. I plan on doing a whole series of courses. This one was an introductory course, so keep that in mind if you are already very familiar with Visualforce. I stressed using declarative solutions and use of standard controllers whenever possible. I really do believe in the KISS (Keep it Simple Stupid) methodology.

Check out one of the free videos Lynda.com makes available:

http://www.lynda.com/player/embed/197238?fs=3&tr=utm_medium=ldc-partner;utm_source=SSPRC;utm_content=11889;utm_campaign=CD16309;aid=CD16309;bid=11889&w=560&h=315;subID5=197238&ps=paused

Oh, and this is the info on the course:

Course Description:
Start developing custom interfaces for the Force.com platform (including Salesforce) using Visualforce. Sara Morgan walks you through the basics of Visualforce, explores its MVC backbone, issues instructions for downloading a free developer edition of the software, and helps you decide if Visualforce is right for your organization. She then explores how to build pages out of common components; enhance pages with tabs, controllers, and extensions; and use the Developer Console to perform more advanced operations—such as editing multiple records, configuring error handling, and unit testing your code. Along the way, you’ll encounter a series of coding challenges that let you practice and expand your Visualforce coding skills.

Topics Include:
What is Visualforce?
Registering for an account
Building a Visualforce page
Building a tabbed page
Configuring permissions
Using standard list controllers and custom controllers
Exploring unit testing

Duration:
3h 4m