' P '

whatever I will forget

非同期Apex futureメソッド

future Apexとは

  • future Apex は、後でシステムリソースが使用可能になったときに複数の処理を別個のスレッドで実行するために使用する

サンプルfuture メソッドの構文

  • future メソッドは静的メソッドである必要がある
  • void型のみを返す
  • 指定する引数は下記の通り
    • プリミティブデータ型
    • プリミティブデータ型の配列
    • プリミティブデータ型のコレクション
  • 引数として標準/カスタムオブジェクトを指定することはできない
  • future メソッドがコールされた順序で実行される保証はない
global class SomeClass {
  @future
  public static void someFutureMethod(List<Id> recordIds) {
    List<Account> accounts = [Select Id, Name from Account Where Id IN :recordIds];
    // process account records to do awesome stuff
  }
}

サンプルコールアウトコード

  • 外部サービスまたは API への Web サービスコールアウトを実行するには、(callout=true) でマークされた future メソッドを使用する
public class SMSUtils {
    // Call async from triggers, etc, where callouts are not permitted.
    @future(callout=true)
    public static void sendSMSAsync(String fromNbr, String toNbr, String m) {
        String results = sendSMS(fromNbr, toNbr, m);
        System.debug(results);
    }
    // Call from controllers, etc, for immediate processing
    public static String sendSMS(String fromNbr, String toNbr, String m) {
        // Calling 'send' will result in a callout
        String results = SmsMessage.send(fromNbr, toNbr, m);
        insert new SMS_Log__c(to__c=toNbr, from__c=fromNbr, msg__c=results);
        return results;
    }
}

サンプルテストクラス

  • テストコードを startTeststopTest テストメソッドで囲む
  • システムが startTest の後に実行されたすべての非同期コールを収集する
  • stopTest が実行されると、これらの収集された非同期プロセスがすべて同期して実行される
@isTest
global class SMSCalloutMock implements HttpCalloutMock {
    global HttpResponse respond(HttpRequest req) {
        // Create a fake response
        HttpResponse res = new HttpResponse();
        res.setHeader('Content-Type', 'application/json');
        res.setBody('{"status":"success"}');
        res.setStatusCode(200);
        return res;
    }
}
@IsTest
private class Test_SMSUtils {
  @IsTest
  private static void testSendSms() {
    Test.setMock(HttpCalloutMock.class, new SMSCalloutMock());
    Test.startTest();
      SMSUtils.sendSMSAsync('111', '222', 'Greetings!');
    Test.stopTest();
    // runs callout and check results
    List<SMS_Log__c> logs = [select msg__c from SMS_Log__c];
    System.assertEquals(1, logs.size());
    System.assertEquals('success', logs[0].msg__c);
  }
}