場合によっては、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='[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;
}
}
ベストアンサー1
ここには 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 エラーは発生しなくなります。