2010-03-05 41 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

相關問題