Cómo evitar el error de la operación mixed_dml en las pruebas de Salesforce que crean usuarios

StackOverflow https://stackoverflow.com/questions/2387475

Pregunta

A veces, en las pruebas de Salesforce, debe crear objetos de usuario para ejecutar parte de la prueba como un tipo de usuario SPECIIFC.

Sin embargo, desde la actualización de Salesforce Summer 08, los intentos de crear objetos de usuario y objetos normales (como cuentas) en la misma prueba conducen al siguiente error:

Mixed_dml_operation, operación DML en el objeto de configuración no está permitido después de haber actualizado un objeto no setup (o viceversa): usuario, objeto original: cuenta

Tenga en cuenta que el error no ocurre cuando ejecuta las pruebas de Eclipse/Force.com IDE, pero sucede cuando se despliega en Salesforce y luego ejecuta las pruebas desde Salesforce.

¿Cómo reescribo mis pruebas para evitar este error?

Aquí hay un ejemplo simple de una prueba que causa el error:

static testMethod void test_mixed_dmlbug() {        
    Profile p = [select id from profile where name='(some profile)'];
    UserRole r = [Select id from userrole where name='(some role)'];
    User u = new User(alias = 'standt', email='standarduser@testorg.com', 
            emailencodingkey='UTF-8', lastname='Testing', 
            languagelocalekey='en_US', 
            localesidkey='en_US', profileid = p.Id, userroleid = r.Id,
            timezonesidkey='America/Los_Angeles', 
            username='standarduser@testorg.com');
    Account a = new Account(Firstname='Terry', Lastname='Testperson');
    insert a;

    System.runAs(u) {
        a.PersonEmail = 'test@madeupaddress.com';
        update a;
    }

}
¿Fue útil?

Solución

No hay muchas personas de Salesforce aquí, supongo.

Encontré una solución, no sé por qué funciona, pero funciona.

Todas las partes de la prueba que acceden a los objetos normales deben envolverse en un sistema. Runas que usan explícitamente al usuario actual, así:

User thisUser = [ select Id from User where Id = :UserInfo.getUserId() ];
System.runAs ( thisUser ) {
    // put test setup code in here
}

Entonces, el ejemplo de text_mixed_dmlbug dado en la pregunta, se convertiría en:

static testMethod void test_mixed_dmlbug() {  
    User u;
    Account a;      
    User thisUser = [ select Id from User where Id = :UserInfo.getUserId() ];
    System.runAs ( thisUser ) {
        Profile p = [select id from profile where name='(some profile)'];
        UserRole r = [Select id from userrole where name='(some role)'];
        u = new User(alias = 'standt', email='standarduser@testorg.com', 
            emailencodingkey='UTF-8', lastname='Testing', 
            languagelocalekey='en_US', 
            localesidkey='en_US', profileid = p.Id, userroleid = r.Id,
            timezonesidkey='America/Los_Angeles', 
            username='standarduser@testorg.com');
        a = new Account(Firstname='Terry', Lastname='Testperson');
        insert a;
    }
    System.runAs(u) {
        a.PersonEmail = 'test@madeupaddress.com';
        update a;
    }

}

Luego, los errores de Operación Mixed_DML dejan de suceder.

Otros consejos

Parece que has encontrado una solución. Solo quería intentar borrar por qué obtienes este error.

Creo que te estás encontrando con este problema (por http://www.salesforce.com/us/developer/docs/apexcode/content/apex_dml_non_mix_sobjects.htm):

SOBECTS que no se pueden usar juntos en operaciones DML

Algunos sobrios requieren que realice operaciones DML con solo un tipo por transacción. Por ejemplo, no puede insertar una cuenta, luego insertar un usuario o un miembro del grupo en una sola transacción. Los siguientes SOBjects no se pueden usar juntos en una transacción:

* Group1
* GroupMember
* QueueSObject
* User2
* UserRole
* UserTerritory
* Territory

Importante, la principal excepción a esto es cuando está utilizando el método Runas en una prueba.

además, el Notas de lanzamiento de verano 08 (Ese enlace es un PDF) Diga:

En las versiones anteriores, en una sola transacción que involucró desencadenantes, puede realizar operaciones de DML en más de un tipo de SOBject, por ejemplo, puede insertar una cuenta y luego insertar un usuario. A partir del verano '08, solo puede realizar operaciones DML en un solo tipo de SOBject de la siguiente lista de SOBjects.

Por ejemplo, no puede insertar una cuenta, luego insertar un usuario o actualizar un grupo, luego insertar un miembro del grupo.

  • Grupo
  • Miembro del grupo
  • Colegio de colas
  • Usuario
  • Rol del usuario
  • Territorio de usuario
  • Territorio

Además, el usuario y el territorio ahora admiten las operaciones de inserción y actualización de DML, y Userrole ahora admite las operaciones DML de Eliminar, actualizar y Upsert.

Las operaciones de APEX DML no son compatibles con los siguientes SOBJECTS:

  • ActoryterritoryAsignNmentRule
  • ActualterritoryAssignmentRuleItem
  • UseraccountTeamMember

Este comportamiento en realidad está documentado en la documentación de Salesforce: http://www.salesforce.com/us/developer/docs/apexcode/index_left.htm#starttopic=content/apex_dml_non_mix_sobjects.htm?searchtype. Lea dónde dice "importante, la principal excepción a esto es cuando está utilizando el método Runas en una prueba"

Acabo de encontrar esto en la documentación:

Otros usos de runAs

También puedes usar el runAs Método para realizar operaciones de DML mixtas en su prueba encerrando las operaciones de DML dentro del runAs bloquear. De esta manera, omite el error DML mixto que de otro modo se devuelve al insertar o actualizar objetos de configuración junto con otros sObjects. Ver sObjects Que no se pueden usar juntos en operaciones DML.

Entonces parece el RunAs La solución no es una solución, pero Salesforce asume como la única forma de seguir el problema de DML mixto.

Espero que esto ayude

Referencia

Este error es muy común cuando se intenta crear registros de usuarios y otros objetos en una sola transacción en APEX.

Solución alternativa en la clase APEX/activador: Use el método futuro para crear el usuario cuando se encuentre el error

Solución alternativa en la clase de prueba: no intente crear un nuevo usuario de los datos, en su lugar, use))>

Código -snippet AT -https://thesalesforcedev.blogspot.com/2019/07/mixeddmloperation-dml-operation-on.html

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top