8
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

HttpCalloutMock と StubProvider のお試し

Last updated at Posted at 2019-05-30

#1.概要
HttpCalloutMock と StubProvider は同じ目的を果たします。
Apex ランタイム人事前に用意した擬似応答(偽物)を返却する。

HttpCalloutMockはクラス単位です。
StubProviderはメソッド単位です。

#2.HttpCalloutMockの使用パターン
0.HttpCalloutMockインターフェースを実装するクラス作成
1.テストデータ作成
2.Test.setMock
3.Test.startTest
4.テストメソッド起動
5.Test.stopTest
6.結果検証

#3.StubProviderの使用パータン
0.StubProvider インターフェースを実装するクラス作成
1.テストデータ作成
2.Test.createStub
 ※返却値は重要です。該当返却値しかモックできません。
3.Test.startTest
4.テストメソッド起動
5.Test.stopTest
6.結果検証

#4.お試し例


public class AnimalsCallouts {
    public HttpResponse makeGetCallout() {
        system.debug('makeGetCallout処理');
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        request.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals');
        request.setMethod('GET');
        HttpResponse response = http.send(request);
        return response;
    }
    public HttpResponse makePostCallout() {
        system.debug('makePostCallout処理');
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        request.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals');
        request.setMethod('POST');
        request.setHeader('Content-Type', 'application/json;charset=UTF-8');
        request.setBody('{"name":"mighty moose"}');
        HttpResponse response = http.send(request);
        return response;
    }
}

@isTest
private class AnimalsCalloutsTest {
    @isTest static  void testGetCallout() {
        Test.setMock(HttpCalloutMock.class, new AnimalsHttpCalloutMock());

        Test.startTest();
        AnimalsCallouts animalsCallout = new AnimalsCallouts();
        HttpResponse response = animalsCallout.makeGetCallout();
        System.debug('testGetCallout:' + response.getBody());
        Test.stopTest();

        String actualValue = response.getBody();
        String expectedValue = '{"animals": ["majestic badger", "fluffy bunny", "scary bear", "chicken", "mighty moose"]}';
        System.assertEquals(actualValue, expectedValue);
    }
    
    @isTest static void testPostCallout() {
        Test.setMock(HttpCalloutMock.class, new AnimalsHttpCalloutMock());

        Test.startTest();
        AnimalsCallouts animalsCallout = new AnimalsCallouts();
        HttpResponse response = animalsCallout.makePostCallout();
        System.debug('testGetCallout:' + response.getBody());
        Test.stopTest();

        String actualValue = response.getBody();
        String expectedValue = '{"animals": ["majestic badger", "fluffy bunny", "scary bear", "chicken", "mighty moose"]}';
        System.assertEquals(actualValue, expectedValue);
    }
    
    @isTest static  void testGetCalloutStub() {
        AnimalsCallouts animalsCallout = (AnimalsCallouts)Test.createStub(AnimalsCallouts.class, new AnimalsCalloutStubProvider());
        
        Test.startTest();
        HttpResponse response = animalsCallout.makeGetCallout();
        System.debug('testGetCalloutStub:' + response.getBody());
        Test.stopTest();
        
        String actualValue = response.getBody();
        String expectedValue = '{"animals": ["000", "000", "000", "000", "000"]}';
        System.assertEquals(actualValue, expectedValue);
    }
    
    @isTest static void testPostCalloutStub() {
        AnimalsCallouts animalsCallout = (AnimalsCallouts)Test.createStub(AnimalsCallouts.class, new AnimalsCalloutStubProvider());
        
        Test.startTest();
        HttpResponse response = animalsCallout.makePostCallout();
        System.debug('testPostCalloutStub:' + response.getBody());
        Test.stopTest();
        
        String actualValue = response.getBody();
        String expectedValue = '{"animals": ["111", "111", "111", "111", "111"]}';
        System.assertEquals(actualValue, expectedValue);
    }

    // HttpCalloutMockインターフェースを実装するクラス作成
    private class AnimalsHttpCalloutMock implements HttpCalloutMock {
        public HTTPResponse respond(HTTPRequest request) {
            HttpResponse response = new HttpResponse();
            response.setHeader('Content-Type', 'application/json');
            response.setBody('{"animals": ["majestic badger", "fluffy bunny", "scary bear", "chicken", "mighty moose"]}');
            response.setStatusCode(200);
            return response; 
        }
    }
    
    // StubProvider インターフェースを実装するクラス作成
    private class AnimalsCalloutStubProvider implements System.StubProvider {
        public Object handleMethodCall(Object stubbedObject, String stubbedMethodName, Type returnType, List<Type> listOfParamTypes, List<String> listOfParamNames,  List<Object> listOfArgs) {
            if(stubbedMethodName == 'makeGetCallout') {
                HttpResponse response = new HttpResponse();
                response.setHeader('Content-Type', 'application/json');
                response.setBody('{"animals": ["000", "000", "000", "000", "000"]}');
                response.setStatusCode(200);
                return response;
                
            } else if (stubbedMethodName == 'makePostCallout') {
                HttpResponse response = new HttpResponse();
                response.setHeader('Content-Type', 'application/json');
                response.setBody('{"animals": ["111", "111", "111", "111", "111"]}');
                response.setStatusCode(200);
                return response;
            }
            return null;
        }
    }
}

#5.Apex スタブ API の制限事項
Apex スタブ API を操作するときは次の点に注意してください。

  • 模造されるオブジェクトは、Test.createStub() メソッドへのコールと同じ名前空間にある必要があります。ただし、StubProvider インターフェースの実装は別の名前空間でも構いません。
  • 次の Apex 要素は模造できません。
  • 静的メソッド (future メソッドを含む)
    • 非公開メソッド
    • プロパティ (getter および setter)
    • トリガ
    • 内部クラス
    • システム型
    • Batchable インターフェースを実装するクラス
    • 非公開コンストラクタのみを持つクラス
  • 戻り値の型またはパラメータの型としてイテレータは使用できません。

#6.参照
Use Mocks and Stub Objects
Apex REST コールアウト
スタブ API を使用したモックフレームワークの作成
Apex スタブ API を使用してテストクラスを作成する

8
5
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
8
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?