Pergunta

Às vezes, nos testes do Salesforce, você precisa criar objetos Usuário para executar parte do teste como um tipo específico de usuário.

No entanto, desde a atualização do Salesforce Summer 08, as tentativas de criar objetos de usuário e objetos normais (como contas) no mesmo teste levam ao seguinte erro:

MIXED_DML_OPERATION, a operação DML no objeto de configuração não é permitida após você ter atualizado um objeto não configurado (ou vice-versa):Usuário, objeto original:Conta

Observe que o erro não ocorre quando você executa os testes no IDE Eclipse/Force.com, mas acontece quando você implanta no Salesforce e, em seguida, executa os testes no Salesforce.

Como reescrevo meus testes para evitar esse erro?

Aqui está um exemplo simples de um teste que causa o erro:

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;
    }

}
Foi útil?

Solução

Ainda não há muitas pessoas do Salesforce aqui, eu acho.

Encontrei uma solução, não sei por que funciona, mas funciona.

Todas as partes do teste que acessam objetos normais precisam ser embrulhados em um sistema.RUNAS que usa explicitamente o usuário atual, como este:

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

Portanto, o exemplo text_mixed_dmlbug dado na pergunta se tornaria:

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;
    }

}

Em seguida, os erros de Mixed_DML_operation param de acontecer.

Outras dicas

Parece que você encontrou uma solução alternativa.Eu só queria tentar esclarecer por que você recebeu esse erro.

Acho que você está enfrentando esse problema (por http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_dml_non_mix_sobjects.htm):

sObjects que não podem ser usados ​​juntos em operações DML

Alguns sObjects exigem que você execute operações DML em apenas um tipo por transação.Por exemplo, você não pode inserir uma conta e depois inserir um usuário ou membro de um grupo em uma única transação.Os seguintes sObjects não podem ser usados ​​juntos em uma transação:

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

Importante A principal exceção a isso é quando você está usando o método Runas em um teste.

Além disso, o Notas de lançamento do verão 08 (esse link é um PDF) diga:

Em versões anteriores, em uma única transação que envolveu gatilhos, você pode executar operações de DML em mais de um tipo de objeto, por exemplo, você pode inserir uma conta e inserir um usuário.A partir do verão '08, você só pode executar operações DML em um único tipo de objeto da lista a seguir de Sobjects.

Por exemplo, você não pode inserir uma conta, inserir um usuário ou atualizar um grupo e inserir um membro do grupo.

  • Grupo
  • Membro do grupo
  • QueueSObject
  • Do utilizador
  • Papel do usuário
  • Território do usuário
  • Território

Além disso, o usuário e o território agora suportam a inserção e atualizam as operações DML, e o Userrole agora suporta a inserção, atualiza as operações de exclusão e upsert DML.

As operações do APEX DML não são suportadas nos seguintes Sobjects:

  • Regra de atribuição de território de conta
  • AccountTerritoryAssignmentRuleItem
  • Membro da equipe da conta do usuário

Esse comportamento está realmente documentado na documentação do Salesforce: http://www.salesforce.com/us/developer/docs/apexcode/index_left.htm#starttopic=content/apex_dml_non_mix_sobjects.htm?searchtype. Leia onde diz "IMPORTANTE A PRIMEIRA EXCEÇÃO A isto é quando você está usando o método Runas em um teste"

Acabei de encontrar isso na documentação:

Outros usos de runAs

Você também pode usar o runAs método para executar operações DML mistas em seu teste, colocando as operações DML dentro do runAs bloquear.Dessa forma, você ignora o erro DML misto que seria retornado ao inserir ou atualizar objetos de configuração junto com outros objetos. sObjects.Ver sObjects Isso não pode ser usado em conjunto em operações DML.

Então parece que RunAs solução alternativa não é uma solução alternativa, mas é assumida pela Salesforce como a única maneira de resolver o problema misto de DML.

Espero que isto ajude

Referência

Esse erro é tão comum ao tentar criar registros de usuário e outros objetos em uma única transação no Apex.

Solução alternativa na classe/gatilho Apex: use o método futuro para criar usuário quando encontrado o erro

Solução alternativa na classe de teste: não tente criar um novo dados do usuário, use))>

Snippet de código em -https://thesalesforcecev.blogspot.com/2019/07/mixeddmloperation-dml-operation-on.html

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top