Comment éviter une erreur D'opération mixte DML dans les tests Salesforce qui créent des utilisateurs
parfois, dans Salesforce tests, vous devez créer des objets User pour exécuter une partie du test en tant que type d'utilisateur speciifc.
cependant, depuis la mise à jour Salesforce Summer 08, Les tentatives de créer à la fois des objets utilisateurs et des objets normaux (tels que des comptes) dans le même test conduisent à l'erreur suivante:
MIXED_DML_OPERATION, l'opération DML sur l'objet setup n'est pas autorisée après avoir mis à jour un objet non-setup (ou vice versa): User, original object: Compte
Notez que l'erreur ne se produit pas lorsque vous exécutez les tests à partir d'Eclipse/Force.com IDE, mais il ne se passe lorsque vous déployez pour Salesforce, puis exécutez les tests à partir de l'intérieur de Salesforce.
Comment puis-je reprendre mes tests pour éviter cette erreur?
Voici un exemple simple d'un test qui provoque l'erreur:
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;
}
}
4 réponses
il N'y a pas encore beaucoup de gens de Salesforce ici, je suppose.
j'ai trouvé une solution, je ne sais pas pourquoi cela fonctionne, mais ça fonctionne.
toutes les parties du test qui accèdent aux objets normaux doivent être enveloppées dans un système.runAs qui utilise explicitement l'utilisateur actuel, comme ceci:
User thisUser = [ select Id from User where Id = :UserInfo.getUserId() ];
System.runAs ( thisUser ) {
// put test setup code in here
}
ainsi, l'exemple de méthode text_mixed_dmlbug donné dans la question, deviendrait:
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;
}
}
alors les erreurs MIXED_DML_OPERATION cessent de se produire.
on dirait que vous avez trouvé une solution. Je voulais juste essayer et clair pourquoi vous où obtenir cette erreur.
je pense que vous êtes en cours d'exécution dans cette question (par http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_dml_non_mix_sobjects.htm):
nessobjects Qui Ne peut pas Être Utilisé dans les Opérations DML
certains sObjects exigent que vous effectuiez des opérations DML sur un seul type de transaction. Par exemple, vous ne peut pas insérer un compte, puis insérer un utilisateur ou un membre du groupe dans une seule transaction. Les sObjects suivants ne peuvent pas être utilisés ensemble dans une transaction:
* Group1 * GroupMember * QueueSObject * User2 * UserRole * UserTerritory * Territory
importante la principale exception c'est quand vous utilisez les runAs méthode de test.
En outre, le Eté 08 notes de Version (ce lien est un PDF) say:
Dans les versions précédentes, en un seul opération qui a impliqué des déclencheurs, vous pourrait effectuer des opérations DML plus d'un type de sObject, pour exemple, vous pouvez insérer un compte, ensuite, insérez un utilisateur. À compter de l'Été '08, vous ne pouvez effectuer DML opérations sur un seul type de sObject à partir de la liste suivante des nessobjects.
Par exemple, vous ne pouvez pas insérer un compte, puis insérer un utilisateur, ou mettre à jour un groupe, puis insérez un groupe membre.
- Groupe
- GroupMember
- QueueSObject
- Utilisateur
- UserRole
- Userterritorium
- Territoire
en plus, Utilisateur et territoire maintenant prise en charge de l'insertion et de la mise à jour DML opérations et rôle D'utilisateur prend maintenant en charge l'insertion, la mise à jour et la suppression et upsert opérations DML.
Les opérations DML D'Apex ne sont pas supportées sur la suivante nessobjects:
- AccountTerritoryAssignmentRule
- AccountTerritoryAssignmentRuleItem
- UserAccountTeamMember
ce comportement est en fait documenté dans la documentation de salesforce: http://www.salesforce.com/us/developer/docs/apexcode/index_Left.htm#StartTopic=Content/apex_dml_non_mix_sobjects.htm?SearchType. Lisez où il est dit " Important La principale exception est lorsque vous utilisez la méthode runAs dans un test"
je Viens de trouver ce dans la documentation:
autres utilisations de
runAs
vous pouvez aussi utiliser le
runAs
méthode pour effectuer des opérations DML mixtes dans votre test en enfermant les opérations DML dans lerunAs
bloc. De cette façon, vous contournez l'erreur DML mélangée qui est par ailleurs retournée lors de l'insertion ou de la mise à jour d'objets setup en même temps que d'autressObjects
. VoirsObjects
qui ne peuvent pas être utilisés ensemble dans les opérations DML.
Donc, c' apparemment, le RunAs
la solution de contournement n'est pas une solution de contournement, mais Salesforce la considère comme la seule solution pour résoudre le problème mixte de DML.
Espérons que cette aide