Come evitare l'errore MIXED_DML_OPERATION nei test Salesforce che creano gli utenti
-
24-09-2019 - |
Domanda
A volte in Salesforce test è necessario creare oggetti Utente per eseguire parte del test come un tipo speciifc di utenti.
Tuttavia, poiché l'aggiornamento Salesforce Summer 08, tentativi di creare entrambi gli oggetti utente e oggetti normali (come i conti) nello stesso puntale per il seguente errore:
MIXED_DML_OPERATION, operazione DML in oggetto l'installazione non è consentito dopo aver aggiornato un oggetto non-setup (o viceversa): L'utente, oggetto originale: account
Si noti che l'errore non si verifica quando si eseguono i test da Eclipse / Force.com IDE, ma succede quando si distribuisce a Salesforce e quindi eseguire i test all'interno di Salesforce.
Come faccio a riscrivere le mie prove per evitare questo errore?
Ecco un semplice esempio di un test che causa l'errore:
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;
}
}
Soluzione
Non molte Salesforce persone qui ancora, immagino.
ho trovato una soluzione, non so perché funziona, ma funziona.
Tutte le parti del test di accesso oggetti normali devono essere avvolti in uno System.runAs che utilizza esplicitamente l'utente corrente, in questo modo:
User thisUser = [ select Id from User where Id = :UserInfo.getUserId() ];
System.runAs ( thisUser ) {
// put test setup code in here
}
Quindi, il metodo esempio text_mixed_dmlbug data in questione, sarebbe diventato:
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;
}
}
Poi i MIXED_DML_OPERATION errori STOP accadendo.
Altri suggerimenti
Sembra aver trovato una soluzione. Volevo solo per cercare di chiarire il motivo per cui in cui questo errore.
Credo che si esegue in questo problema (per http: //www.salesforce.com/us/developer/docs/apexcode/Content/apex_dml_non_mix_sobjects.htm ):
sObjects che non possono essere utilizzati insieme a DML Operations
Alcuni sObjects richiedono di eseguire operazioni DML su un solo tipo per ogni transazione. Ad esempio, non è possibile inserire un account, quindi inserire un utente o un membro del gruppo in un'unica transazione. I seguenti sObjects non possono essere utilizzati insieme in una transazione:
* Group1 * GroupMember * QueueSObject * User2 * UserRole * UserTerritory * Territory
Importante L'eccezione principale per questo è quando si stanno utilizzando i runAs Metodo in un test.
In aggiunta, le Estate 08 Note di rilascio (che collegamento è un PDF) diciamo:
Nelle versioni precedenti, in un unico transazione che trigger coinvolti, è possibile eseguire operazioni DML su più di un tipo di sObject, per ad esempio, si potrebbe inserire un account, quindi inserire un utente. Come di estate '08, è possibile eseguire solo DML operazioni su un unico tipo di sObject dalla seguente lista di sObjects.
Per esempio, non è possibile inserire un conto, quindi inserire un utente o aggiornamento un gruppo, quindi inserire un gruppo membro.
- gruppo
- GroupMember
- QueueSObject
- utente
- UserRole
- UserTerritory
- Territorio
In aggiunta, l'utente e Territorio ora sostenere l'inserimento e aggiornamento DML operazioni, e UserRole ora supporta l'inserimento, aggiornamento elimina e upsert operazioni DML.
Operazioni Apex DML non sono supportate sui seguenti sObjects:
- AccountTerritoryAssignmentRule
- AccountTerritoryAssignmentRuleItem
- UserAccountTeamMember
Questo comportamento è in realtà documentata nella documentazione di Salesforce: http://www.salesforce.com/us/developer/docs/apexcode/index_Left.htm#StartTopic=Content/apex_dml_non_mix_sobjects.htm?SearchType . Leggi dove si dice "Importante L'eccezione principale per questo è quando si utilizza il metodo runAs in un test "
Appena trovato questo nella documentazione:
Altri usi di
runAs
Si può anche utilizzare il metodo
runAs
per eseguire operazioni DML misti nel test racchiudendo le operazioni DML all'interno del bloccorunAs
. In questo modo, si bypass l'errore DML mista che è altrimenti restituito durante l'inserimento o l'aggiornamento di installazione gli oggetti insieme ad altrisObjects
. VederesObjects
che non possono essere utilizzati insieme in operazioni DML.
Quindi sembra che la soluzione RunAs
non è una soluzione, ma non si assume Salesforce come l'unico modo di andare dalla questione DML mista.
Spero che questo aiuti
Questo errore è così comune quando si tenta di creare altri record oggetti utente e in una singola transazione in apice.
Per risolvere il problema in apice classe / trigger: Metodo di uso futuro per la creazione di utente quando ha rilevato l'errore
Per risolvere il problema in classe di test: non provare a creare un nuovo dati degli utenti, invece usare))>
code-snippet - https://thesalesforcedev.blogspot.com/2019/07/ mixeddmloperation-DML-operation-on.html