2010-03-05 37 views
30

有时在Salesforce测试中,您需要创建用户对象以将特定类型的用户作为测试的一部分运行。如何避免Salesforce测试中创建用户的MIXED_DML_OPERATION错误

然而,由于Salesforce的夏季08更新,尝试创建在同一个测试引线的两个用户对象和正常对象(如会计)以下错误:该错误不

MIXED_DML_OPERATION, DML operation on setup object is not permitted after you have updated a non-setup object (or vice versa): User, original object: Account

注当您从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='[email protected]', 
      emailencodingkey='UTF-8', lastname='Testing', 
      languagelocalekey='en_US', 
      localesidkey='en_US', profileid = p.Id, userroleid = r.Id, 
      timezonesidkey='America/Los_Angeles', 
      username='[email protected]'); 
    Account a = new Account(Firstname='Terry', Lastname='Testperson'); 
    insert a; 

    System.runAs(u) { 
     a.PersonEmail = '[email protected]'; 
     update a; 
    } 

} 

回答

38

没有多少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='[email protected]', 
      emailencodingkey='UTF-8', lastname='Testing', 
      languagelocalekey='en_US', 
      localesidkey='en_US', profileid = p.Id, userroleid = r.Id, 
      timezonesidkey='America/Los_Angeles', 
      username='[email protected]'); 
     a = new Account(Firstname='Terry', Lastname='Testperson'); 
     insert a; 
    } 
    System.runAs(u) { 
     a.PersonEmail = '[email protected]'; 
     update a; 
    } 

} 

然后MIXED_DML_OPERATION错误停止发生。

+0

等待,我们需要插入一个用户记录呢?我认为你可以简单地初始化新的User实例,并直接在system.runAs()中使用 – 2011-09-05 12:42:54

+0

但是如果我需要多个/ new/user,该怎么办?我打算用多个system.runAs()来查看我是否可以为我的新用户设置用户标识符。 – tggagne 2012-03-20 03:08:23

+0

它仍然有效 - 你不需要插入用户。另外,如果您要选择当前用户,system.runAs()的用法是什么? – 2012-05-04 10:36:45

12

您似乎已经找到了解决方法。我只是想尝试澄清为什么你在哪里得到这个错误。

我认为你正在运行到这个问题(每http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_dml_non_mix_sobjects.htm):

sObjects That Cannot Be Used Together in DML Operations

Some sObjects require that you perform DML operations on only one type per transaction. For example, you cannot insert an account, then insert a user or a group member in a single transaction. The following sObjects cannot be used together in a transaction:

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

Important The primary exception to this is when you are using the runAs method in a test.

此外,Summer 08 Release notes(该链接为一个PDF)说:

In previous releases, in a single transaction that involved triggers, you could perform DML operations on more than one type of sObject, for example, you could insert an account, then insert a user. As of Summer '08, you can only perform DML operations on a single type of sObject from the following list of sObjects.

For example, you cannot insert an account, then insert a user, or update a group, then insert a group member.

  • Group
  • GroupMember
  • QueueSObject
  • User
  • UserRole
  • UserTerritory
  • Territory

In addition, User and Territory now support the insert and update DML operations, and UserRole now supports the insert, update delete and upsert DML operations.

Apex DML operations are not supported on the following sObjects:

  • AccountTerritoryAssignmentRule
  • AccountTerritoryAssignmentRuleItem
  • UserAccountTeamMember
+1

是的,这就是错误的原因,但从SF文档中不太清楚这个限制是否适用于测试方法。似乎在测试中得到这个错误,有些则没有,在developerforce论坛上有一些关于它的讨论,但没有一个是非常清楚的,所以我想我会在这里问......谢谢 – codeulike 2010-03-10 09:37:10

+1

尽管文本“重要此例外的主要例外是当您在测试中使用runAs方法”不再位于引用页面上时,此解决方法仍然有效 – Legolas 2013-07-30 08:38:18

6
+0

在测试方法中仍会出现此错误 – tponthieux 2012-05-03 16:31:10

+0

但是在使用runAs方法在测试方法内正确运行。 – 2012-05-23 23:06:53

+0

帮助中的文字在此期间发生了变化,但这个答案今天仍保存了我的培根!如果你不指定UserRoleId,显然你没问题。并且设置UserRoleId的测试在Eclipse中愉快地通过,但是在Web测试运行器中失败... thedailywtf.com,在这里我来... – eyescream 2013-05-21 12:12:47

0

刚刚发现这个文档中的“重要 当您使用在测试中的runAs方法主要例外是”:

Other Uses of runAs

You can also use the runAs method to perform mixed DML operations in your test by enclosing the DML operations within the runAs block. In this way, you bypass the mixed DML error that is otherwise returned when inserting or updating setup objects together with other sObjects . See sObjects That Cannot Be Used Together in DML Operations.

所以它看起来像RunAs解决方法是不是解决方法,而是被Salesforce视为混合DML问题的唯一方法。

希望这有助于

Reference

相关问题