0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Salesforce】User更新が含まれるFlowでテストクラスが失敗する理由とその対策(MIXED_DML_OPERATION/FIELD_INTEGRITY_EXCEPTION対策)

Posted at

💡背景

SalesforceでFlowやトリガーなどでUserオブジェクトを更新するケースでは、裏でAccountやContactなどの**「設定オブジェクト」**も一緒に更新されることがあり、テストクラスでのエラーを引き起こすことがあります。

🔧 発生するエラー

FIELD_INTEGRITY_EXCEPTION

System.DmlException: Insert failed. First exception on row 0; first error: FIELD_INTEGRITY_EXCEPTION, only portal users can be associated to a contact.

→ これは**ポータルユーザー(Communityユーザー)**を作成 or 更新しようとした際に、Contactとの関連付けが正しくない場合に発生します。


MIXED_DML_OPERATION

DmlException: Mixed DML operation between setup and non-setup objects

→ これは User(設定オブジェクト)と、AccountContact(非設定オブジェクト)を 同じトランザクション内でDML操作しようとした場合に出る エラーです。


💥 これらのエラーが起こる背景

  • Flowやトリガーで User を更新する
  • そのUserがポータルユーザー(=Contactと紐づく必要あり)
  • テストクラスで UserAccount / Contact を同時にInsert/Update
  • FIELD_INTEGRITY_EXCEPTION or MIXED_DML_OPERATION が発生

✅ 解決策

🔹テストクラスでのトランザクションを分ける(@TestSetup を使う)

Salesforceでは User を他のオブジェクトと同時に操作するのを避けるため、以下のように トランザクションを分ける ことで MIXED_DML_OPERATION を回避できます。


🧪 テストクラス例


@isTest
private class UserFlowTest {

    @TestSetup
    static void setup() {
        // 取引先・責任者を事前に作成
        Account acc = new Account(Name = 'Test');
        insert acc;

        Contact con = new Contact(LastName = 'Test Contact', AccountId = acc.Id);
        insert con;

        contactId = con.Id;
    }

    @isTest
    static void testFlow() {


        // プロファイルを取得したり、取引先責任者を取得したり
    
        Test.startTest();

        // User作成(@TestSetupとは別トランザクションで処理)
        User u = new User(
            Username = 'testuser@example.com.test',
            LastName = 'User',
            Email = 'testuser@example.com',
            Alias = 'tuser',
            TimeZoneSidKey = 'Asia/Tokyo',
            LocaleSidKey = 'ja_JP',
            EmailEncodingKey = 'UTF-8',
            LanguageLocaleKey = 'ja',
            ProfileId = profileId,
            ContactId = contactId,
            CommunityNickname = 'testuser'
        );
        insert u;
        // insert後にフローが動いてもトランザクション内ではユーザーのみのためMIXED_DML_OPERATIONない

        System.runAs(u) {
            Test.startTest();
            try {
                // テストしたい処理
            } catch (Exception e) {
                System.debug('テスト実行中に例外が発生: ' + e.getMessage());
            }
            Test.stopTest();
        }
    }
}



📌補足

課題 解決方法
FIELD_INTEGRITY_EXCEPTION Contactの事前作成+正しいプロファイル設定
MIXED_DML_OPERATION User@TestSetup 内で insert することで分離

✅ まとめ

  • UserのInsert/Updateには注意が必要(特にCommunityユーザー)
  • AccountContactとの整合性と、DMLの順序・分離がポイント
  • テストクラスでは @testSetup で非設定オブジェクトだけ作成
  • Userの操作は必ず テストメソッド内で行い、DMLの分離を意識する
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?