如何避免在创建用户的Salesforce测试中出现MIXED_DML_OPERATION错误
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何避免在创建用户的Salesforce测试中出现MIXED_DML_OPERATION错误相关的知识,希望对你有一定的参考价值。
有时在Salesforce测试中,您需要创建User对象以作为特定类型的用户运行部分测试。
但是,自Salesforce Summer 08更新以来,尝试在同一测试中创建用户对象和普通对象(如帐户)会导致以下错误:
MIXED_DML_OPERATION,更新非安装对象后,不允许对安装对象进行DML操作(反之亦然):用户,原始对象:帐户
请注意,从Eclipse / Force.com IDE运行测试时不会发生错误,但是当您部署到Salesforce然后从Salesforce中运行测试时,确实会发生错误。
如何重新编写测试以避免此错误?
以下是导致错误的测试的简单示例:
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;
}
}
我猜这里的Salesforce人员不多。
我找到了一个解决方案,我不知道它为什么有效,但它确实有效。
访问普通对象的测试的所有部分都需要包装在显式使用当前用户的System.runAs中,如下所示:
User thisUser = [ select Id from User where Id = :UserInfo.getUserId() ];
System.runAs ( thisUser ) {
// put test setup code in here
}
因此,问题中给出的示例text_mixed_dmlbug方法将变为:
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;
}
}
然后MIXED_DML_OPERATION错误停止发生。
好像你找到了一个解决方法。我只是想尝试清理为什么你在哪里得到这个错误。
我认为你遇到了这个问题(根据http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_dml_non_mix_sobjects.htm):
在DML操作中无法一起使用的sObjects
某些sObject要求您对每个事务仅对一种类型执行DML操作。例如,您无法插入帐户,然后在单个事务中插入用户或组成员。以下sObjects不能在事务中一起使用:
* Group1 * GroupMember * QueueSObject * User2 * UserRole * UserTerritory * Territory
重要说明这一点的主要例外是在测试中使用runAs方法时。
此外,Summer 08 Release notes(该链接是PDF)说:
在以前的版本中,在涉及触发器的单个事务中,您可以对多种类型的sObject执行DML操作,例如,您可以插入帐户,然后插入用户。从Summer '08开始,您只能从以下sObject列表中对单一类型的sObject执行DML操作。
例如,您无法插入帐户,然后插入用户或更新组,然后插入组成员。
- 组
- GroupMember
- QueueSObject
- 用户
- UserRole的
- UserTerritory
- 领土
此外,User和Territory现在支持插入和更新DML操作,UserRole现在支持插入,更新删除和upsert DML操作。
以下sObjects不支持Apex DML操作:
- AccountTerritoryAssignmentRule
- AccountTerritoryAssignmentRuleItem
- UserAccountTeamMember
salesforce文档中实际记录了此行为:http://www.salesforce.com/us/developer/docs/apexcode/index_Left.htm#StartTopic=Content/apex_dml_non_mix_sobjects.htm?SearchType。阅读它所说的“重要”这个的主要例外是当你在测试中使用runAs方法时
刚刚在文档中找到了这个:
其他用途的
runAs
您还可以使用
runAs
方法在测试中通过将DML操作包含在runAs
块中来执行混合DML操作。通过这种方式,您可以绕过在与其他sObjects
一起插入或更新设置对象时返回的混合DML错误。请参阅在DML操作中无法一起使用的sObjects
。
因此,看起来RunAs
解决方法不是一种解决方法,但Salesforce认为这是解决混合DML问题的唯一方法。
希望这可以帮助
以上是关于如何避免在创建用户的Salesforce测试中出现MIXED_DML_OPERATION错误的主要内容,如果未能解决你的问题,请参考以下文章
如何在salesforce中建立opportunity object
我们正在使用 JMeter 测试 Salesforce 应用程序。单个用户从 JMeter 登录需要 35 秒,但是从 UI 可能需要 15 秒