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?

Part 6: テストクラスでのエラーハンドリングとカスタム例外の活用

Posted at

Part 6: テストクラスでのエラーハンドリングとカスタム例外の活用

前回は ガバナ制限を考慮したエラーハンドリングバッチ処理の例外処理 について解説しました。
今回は テストクラスでのエラーハンドリングカスタム例外の活用 に焦点を当てます。


1. テストクラスでのエラーハンドリング

Salesforce では、Apex コードの 75% 以上をカバーするテストクラスが必須 です。
特に エラーハンドリングを適切にテストしないと、実際の運用時に問題が発生する可能性 があります。


1.1. System.assertException() で例外発生を確認

例外が正しくスローされるかを確認するには System.assertException() を使います。

✅ OK 例: try-catch のテスト

@isTest
private class SampleTest {
    @isTest
    static void testExceptionHandling() {
        try {
            MyClass.methodThatThrowsException();
            System.assert(false, '例外が発生するはずなのに、発生しませんでした');
        } catch (CustomException e) {
            System.assertEquals('エラーメッセージ', e.getMessage());
        }
    }
}

このテストでは、例外が発生することを前提に System.assertException() で検証 しています。


1.2. Test.startTest() / Test.stopTest() を使ったテスト

バッチ処理や非同期処理のエラーハンドリングをテストする場合、
Test.startTest() / Test.stopTest() を使って非同期処理を強制実行 します。

✅ OK 例: バッチ処理の例外テスト

@isTest
private class BatchErrorTest {
    @isTest
    static void testBatchErrorHandling() {
        // テストデータ作成
        List<Account> accounts = new List<Account>();
        for (Integer i = 0; i < 200; i++) {
            accounts.add(new Account(Name = 'Test Account ' + i));
        }
        insert accounts;

        // バッチ実行
        Test.startTest();
        BatchApexExample batch = new BatchApexExample();
        Database.executeBatch(batch, 50);
        Test.stopTest();
        
        // エラーログを検証
        List<ErrorLog__c> logs = [SELECT Message__c FROM ErrorLog__c];
        System.assert(logs.size() > 0, 'エラーログが作成されているはず');
    }
}

このテストでは、バッチ処理のエラーを再現し、エラーログが作成されることを検証 しています。


2. カスタム例外 (CustomException) の活用

標準の Exception だけでなく、カスタム例外を作成するとエラーハンドリングがより明確になります


2.1. カスタム例外の定義

Apex では extends Exception を使って独自の例外を作成 できます。

✅ OK 例: カスタム例外 InvalidDataException

public class InvalidDataException extends Exception {}

このように 特定のエラーを識別するためのカスタム例外を定義 できます。


2.2. カスタム例外の活用

データのバリデーション時に InvalidDataException を使う ことで、
エラーの種類を明確に分けられます。

✅ OK 例: メソッドでカスタム例外をスロー

public class AccountService {
    public static void validateAccount(Account acc) {
        if (String.isEmpty(acc.Name)) {
            throw new InvalidDataException('アカウント名が空です');
        }
    }
}

この validateAccount() メソッドは、アカウント名が空なら InvalidDataException をスロー します。


2.3. カスタム例外を使ったテスト

カスタム例外が 正しく発生することを検証 します。

✅ OK 例: InvalidDataException のテスト

@isTest
private class AccountServiceTest {
    @isTest
    static void testValidateAccount() {
        try {
            Account acc = new Account();
            AccountService.validateAccount(acc);
            System.assert(false, '例外が発生するはずなのに、発生しませんでした');
        } catch (InvalidDataException e) {
            System.assertEquals('アカウント名が空です', e.getMessage());
        }
    }
}

このテストでは、validateAccount() が正しく例外をスローすることを確認 しています。


3. 例外処理のベストプラクティス

3.1. 例外の種類を明確に分ける

  • DmlException → DML 操作の失敗時 (insert/update/delete のエラー)
  • QueryException → SOQL クエリのエラー (List has no rows for assignment)
  • LimitException → ガバナ制限 (Too many SOQL queries など)
  • CustomException → 独自のエラー (InvalidDataException など)

3.2. try-catch を使う際のポイント

  • キャッチする例外は最小限にする
    try {
        insert account;
    } catch (DmlException e) {
        System.debug('DMLエラー: ' + e.getMessage());
    }
    
    NG 例: Exception e で全てキャッチしてしまう
    try {
        insert account;
    } catch (Exception e) { // すべての例外をキャッチするのは危険
        System.debug('エラー: ' + e.getMessage());
    }
    
    すべての例外をキャッチすると、本来のエラー原因が分かりにくくなる ため注意。

3.3. バッチ処理で例外を記録

  • エラーが発生したレコードはスキップし、エラーログを記録
    global void execute(Database.BatchableContext bc, List<Account> scope) {
        List<Account> successList = new List<Account>();
        
        for (Account acc : scope) {
            try {
                insert acc;
                successList.add(acc);
            } catch (DmlException e) {
                ErrorLog__c log = new ErrorLog__c(Message__c = e.getMessage());
                insert log;
            }
        }
    }
    

まとめ

今回は テストクラスでのエラーハンドリングカスタム例外の活用 について解説しました。

  • System.assertException() を使って例外発生を確認
  • Test.startTest() / Test.stopTest() で非同期処理をテスト
  • カスタム例外 (CustomException) を作成し、明確なエラーハンドリング
  • try-catch で適切に例外をキャッチし、ログを記録

次の Part 7 では、エラーハンドリングの設計パターン (エラーログ管理・リトライ機構) を解説 します!

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?