No Results
Search Tips:
- Please consider misspellings
- Try different search keywords
Newer Version Available
テストメソッドでの混合 DML 操作
テストメソッドでは、DML 操作を実行するコードが System.runAs メソッドブロックで囲まれている場合、「DML 操作で同時に使用できない sObject」に記載された sObject とその他の sObject の間の混合 DML 操作の実行が許可されます。たとえば、これによりロールとその他の sObject を持つユーザを同じテスト内で作成できます。
例: System.runAs ブロックでの混合 DML 操作
1swfobject.registerObject("clippy.codeblock-0", "9");@isTest
2private class MixedDML {
3 static testMethod void mixedDMLExample() {
4 User u;
5 Account a;
6 User thisUser = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()];
7 // Insert account as current user
8 System.runAs (thisUser) {
9 Profile p = [SELECT Id FROM Profile WHERE Name='Standard User'];
10 UserRole r = [SELECT Id FROM UserRole WHERE Name='COO'];
11 u = new User(alias = 'jsmith', email='jsmith@acme.com',
12 emailencodingkey='UTF-8', lastname='Smith',
13 languagelocalekey='en_US',
14 localesidkey='en_US', profileid = p.Id, userroleid = r.Id,
15 timezonesidkey='America/Los_Angeles',
16 username='jsmith@acme.com');
17 insert u;
18 a = new Account(name='Acme');
19 insert a;
20 }
21 }
22}
23テストメソッドで Test.startTest と Test.stopTest を使用して混合 DML エラーを回避する
混合 DML 操作を実行するコードブロックを System.runAs ブロックで囲んでも、混合 DML 例外エラーが返されることがあります。これは、テストメソッドが、グループの削除など、他の操作とは混合できない DML 操作を実行する future メソッドをコールした場合に発生する可能性があります。この場合、混合 DML 例外が返されたら、future メソッドコールを行うコードブロックを、Test.stopTest および Test.startTest ステートメントで囲みます。
この例では、Test.startTest および Test.stopTest ステートメントで delete ステートメントを囲むことにより、テストで混合 DML 例外エラーを回避する方法を示します。delete ステートメントにより、混合 DML 操作は future メソッドで実行されることになるため、ステートメントを Test.startTest および Test.stopTest ステートメントで囲みます。delete ステートメントはトリガを起動し、Util クラスの deleteGroup future メソッドをコールして取引先挿入トリガですでに挿入されていたグループを削除します。
これは、混合 DML 操作を起動するテストクラスです。取引先挿入および削除がトリガを起動します。
1@isTest
2private class RunasTest {
3 static testMethod void mixeddmltest() {
4 // Create the account and group.
5 Account ac = new Account(Name='TEST ACCOUNT');
6 // Group is created in the insert trigger.
7 insert ac;
8 // Set up user
9 User u1 = [SELECT Id FROM User WHERE UserName='testadmin@acme.com'];
10 System.RunAs(u1){
11 // Add startTest and stopTest to avoid mixed DML error
12 Test.startTest();
13 // Delete the account.
14 // Group is deleted through future method call in trigger.
15 delete ac;
16 Test.stopTest();
17 }
18 }
19}これは、グループを挿入する取引先挿入トリガです。
1trigger Account_After_Insert_Trg on Account (after insert) {
2 Group gr = new Group(Name='Test',Type='Regular');
3 insert gr;
4}これは、future メソッドをコールしてグループを削除する取引先削除トリガです。
1trigger Account_Before_Delete_Trg on Account (before delete) {
2 Util.deleteGroup('Test');
3}これは、グループを削除する future メソッドです。
1public with sharing class Util {
2 @future
3 public static void deleteGroup(String grNameSet) {
4 List<Group> grList =
5 [select Id, Name from Group where Name = :grNameSet];
6 delete grList[0];
7 }
8}