---
schema_version: "1"
id: 22e445807c4959da8093d16e05f7f38f177cfc3e775212197685ebea8a6bb156
title: Mixed DML Operations in Test Methods
collection: legacydeveloper
version: current
locale: en-us
portal_url: https://docs.salesforce.com/legacydeveloper/current/en-us/apexcode/apex_dml_non_mix_sobjects_test_methods.md
canonical_url: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_dml_non_mix_sobjects_test_methods.htm
source_site: developer.salesforce.com
content_type: documentation
content_hash: 085ad73291d9c7669f0f203d6f2618f56e7a10e33f61d4b8aa84117946faad3c
description: Test methods allow for performing mixed Data Manipulation Language (DML) operations that include both setup sObjects and other sObjects if the code that performs the DML operations is enclosed within System.runAs method blocks. You can also perform DML in an asynchronous job that your test method calls. These techniques enable you, for example, to create a user with a role and other sObjects in the same test.
---
# Mixed DML Operations in Test Methods

Test methods allow for performing mixed Data Manipulation Language (DML) operations that include both setup sObjects and other sObjects if the code that performs the DML operations is enclosed within System.runAs method blocks. You can also perform DML in an asynchronous job that your test method calls. These techniques enable you, for example, to create a user with a role and other sObjects in the same test.

The setup sObjects are listed in [sObjects That Cannot Be Used Together in DML Operations](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_dml_non_mix_sobjects.htm "DML operations on certain sObjects, sometimes referred to as setup objects, can’t be mixed with DML on non-setup sObjects in the same transaction. This restriction exists because some sObjects affect the user’s access to records in the org. You must insert or update these types of sObjects in a different transaction to prevent operations from happening with incorrect access-level permissions. For example, you can’t update an account and a user role in a single transaction.").

![Note](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/images/icon_note.png)

#### Note

Because validation for mixed DML operations is skipped during deployment, there can be a difference in the number of test failures when tests are deployed versus when run in the user interface.

## Example: Mixed DML Operations in System.runAs Blocks

This example shows how to enclose mixed DML operations within System.runAs blocks to avoid the mixed DML error. The System.runAs block runs in the current user’s context. It creates a test user with a role and a test account, which is a mixed DML operation.

@IsTest
private with sharing class MixedDML {
    @IsTest
    static void mixedDMLExample() {  
        User thisUser = \[SELECT Id FROM User WHERE Id = :UserInfo.getUserId() WITH SYSTEM\_MODE\];
       // Insert account as current user
        System.runAs (thisUser) {
            Profile p = \[SELECT Id FROM Profile WHERE Name='Standard User' WITH SYSTEM\_MODE\];
            UserRole r = \[SELECT Id FROM UserRole WHERE Name='COO' WITH SYSTEM\_MODE\];
            User 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 as system u;
            Account a = new Account(name='Acme');
            insert as system a;
        }
    }
}

## Use @Future to Bypass the Mixed DML Error in a Test Method

Mixed DML operations within a single transaction aren’t allowed. You can’t perform DML on a setup sObject and another sObject in the same transaction. However, you can perform one type of DML as part of an asynchronous job and the others in other asynchronous jobs or in the original transaction. This class contains an @future method to be called by the class in the subsequent example.

public with sharing class InsertFutureUser {
    @Future
    public static void insertUser() {
        Profile p = \[SELECT Id FROM Profile WHERE Name='Standard User' WITH SYSTEM\_MODE\];
        UserRole r = \[SELECT Id FROM UserRole WHERE Name='COO' WITH SYSTEM\_MODE\];
        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 as system futureUser;
    }
}

This class calls the method in the previous class.

@IsTest
public with sharing class UserAndContactTest {
    public @IsTest
    static void testUserAndContact() {
        InsertFutureUser.insertUser();
        Contact currentContact = new Contact(
            firstName = String.valueOf(System.currentTimeMillis()),
            lastName = 'Contact');
        insert as user currentContact;
    }
}