この文章は Salesforce 機械翻訳システムを使用して翻訳されました。詳細はこちらをご参照ください。
英語に切り替える

Newer Version Available

This content describes an older version of this product. View Latest

テストメソッドでの混合 DML 操作

テストメソッドでは、DML 操作を実行するコードが System.runAs メソッドブロックで囲まれている場合、DML 操作で同時に使用できない sObjectに記載された sObject とその他の sObject の間の混合 DML 操作の実行が許可されます。たとえば、これによりロールとその他の sObject を持つユーザを同じテスト内で作成できます。

例: System.runAs ブロックでの混合 DML 操作

この例では、混合 DML 操作を System.runAs ブロックで囲み、混合 DML エラーを回避する方法を示します。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.startTestTest.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}