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];
}
}
サンプルコールアウトコード
- 外部サービスまたは API への Web サービスコールアウトを実行するには、
(callout=true)
でマークされた future メソッドを使用する
public class SMSUtils {
@future(callout=true)
public static void sendSMSAsync(String fromNbr, String toNbr, String m) {
String results = sendSMS(fromNbr, toNbr, m);
System.debug(results);
}
public static String sendSMS(String fromNbr, String toNbr, String m) {
String results = SmsMessage.send(fromNbr, toNbr, m);
insert new SMS_Log__c(to__c=toNbr, from__c=fromNbr, msg__c=results);
return results;
}
}
サンプルテストクラス
- テストコードを
startTest
と stopTest
テストメソッドで囲む
- システムが
startTest
の後に実行されたすべての非同期コールを収集する
stopTest
が実行されると、これらの収集された非同期プロセスがすべて同期して実行される
@isTest
global class SMSCalloutMock implements HttpCalloutMock {
global HttpResponse respond(HttpRequest req) {
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();
List<SMS_Log__c> logs = [select msg__c from SMS_Log__c];
System.assertEquals(1, logs.size());
System.assertEquals('success', logs[0].msg__c);
}
}