TrailHead

ApexでRESTコールアウト【セールスフォース】

TrailHead
この記事は約8分で読めます。

今回はTrailheadのApex インテグレーションサービス内のApex REST コールアウトをやっていきます。
コールアウトとかってそこまで意識することなくて今まであまりやってこなかったんですが、
いいかげんそんなことも言ってられなくなってきたので勉強しようと言うことでやっていきます。
(実は来週デベロッパーの試験控えてるんで、やらないとやばいんですけどね。。。)

ではやっていきましょう!

Hands-on Challenge

Create an Apex class that calls a REST endpoint and write a test class.To pass this challenge, create an Apex class that calls a REST endpoint to return the name of an animal, write unit tests that achieve 100% code coverage for the class using a mock response, and run your Apex tests.

  • The Apex class must be called ‘AnimalLocator’, have a ‘getAnimalNameById’ method that accepts an Integer and returns a String.
  • The ‘getAnimalNameById’ method must call https://th-apex-http-callout.herokuapp.com/animals/:id, using the ID passed into the method. The method returns the value of the ‘name’ property (i.e., the animal name).
  • Create a test class named AnimalLocatorTest that uses a mock class called AnimalLocatorMock to mock the callout response.
  • The unit tests must cover all lines of code included in the AnimalLocator class, resulting in 100% code coverage.
  • Run your test class at least once (via ‘Run All’ tests the Developer Console) before attempting to verify this challenge.

日本語訳

RESTエンドポイントを呼び出すApexクラスを作成し、テストクラスを記述します。
このチャレンジに合格するには、RESTエンドポイントを呼び出して動物の名前を返すApexクラスを作成し、モック応答を使用してクラスの100%コードカバレッジを達成するユニットテストを記述し、Apexテストを実行します

  • Apexクラスは「AnimalLocator」と呼ばれ、整数を受け入れて文字列を返す「getAnimalNameById」メソッドが必要です。
  • 「getAnimalNameById」メソッドは、メソッドに渡されたIDを使用してhttps://th-apex-http-callout.herokuapp.com/animals/:idを呼び出す必要があります。メソッドは、「name」プロパティの値(つまり、動物の名前)AnimalLocatorMockという模擬クラスを使用してコールアウト応答を模擬するAnimalLocatorTestという名前のテストクラスを作成します。
  • 単体テストは、AnimalLocatorクラスに含まれるコードのすべての行をカバーする必要があり、100%のコードカバレッジになります。
  • この課題を検証する前に、テストクラスを少なくとも1回実行します(「すべて実行」を使用して開発者コンソールをテストします)。

解答

さあ、とにかく今回はコードを書いて書いて書きまくる系なのでテンションあがりますね!

まず、今回の要点としては

  • Apexクラス「AnimalLocator」を作成し、「getAnimalNameById」のメソッドがある事。
  • 「getAnimalNameById」にはInteger型のId?を渡して、HTTPコールしてnameプロパティの値を返す。
  • 「AnimalLocatorMock」という擬似クラスで「AnimalLocatorTest」をテストしてカバー率は100%ですよ。

こんな感じです。まず「AnimalLocator」を作っていきます。
「getAnimalNameById」のIdはId型ではなくてIntegerなので気を付けましょう。
,でこれを作成する前に途中のコピーして匿名実行はやっておくとさらに理解はしやすいかと思いますので、
ぜひ実際にやってみてください。
以下「AnimalLocator」のコードです。

public class AnimalLocator {
    public String getAnimalNameById(Integer Id){
        
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        Map<String,Object> animal = new Map<String,Object>();
        
        request.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals/' + Id);
        request.setMethod('GET');
        HttpResponse response = http.send(request);
        if (response.getStatusCode() == 200) {
            
            Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
            animal = (Map<String,Object>) results.get('animal');
        }
        return (String)animal.get('name'); 
    } 
}

途中のコードを参考にすればそんなに難しくはないです。
ポイントはhttps://th-apex-http-callout.herokuapp.com/animals/ + IdのHTTPを呼び出して実際の結果を見るのが良いでしょう。
Trailhead内のサンプルコードはListでしたがMap型になるので要注意です。

次にMockクラスとテストクラスを記述していきます。

Mockクラス

@isTest
global class AnimalLocatorMock {
// Implement this interface method
    global HTTPResponse respond(HTTPRequest request) {
        // Create a fake response
        HttpResponse response = new HttpResponse();
        response.setHeader('Content-Type', 'application/json');
        response.setBody('{"animal":{"id":4,"name":"dog","eats":"meet","says":"bow wow"}}');
        response.setStatusCode(200);
        return response; 
    }
}

Testクラス

@isTest
public class AnimalLocatorTest {
@isTest static  void testGetCallout() {
    //擬似応答用のクラスをインスタンス化
        StaticResourceCalloutMock mock = new StaticResourceCalloutMock();
    //メソッドへ値をセット
        mock.setStaticResource('GetAnimalsResource');
        mock.setStatusCode(200);
        mock.setHeader('Content-Type', 'application/json;charset=UTF-8');
    //擬似応答モードをセット
        Test.setMock(HttpCalloutMock.class, mock);
    //メソッドの呼出
        String result = AnimalLocator.getAnimalNameById(3);
    //返却値の確認
        System.assertEquals(result , 'cat');
    }

でこれでOKだろうと。思ってやったらダメでした。

すなわち、Mockを使ってちゃんとテスト通してねって事でした。
なのでテストクラスに追記です。

    @isTest static void testPostCallout() {
        // モックコールアウトクラスをセット
        Test.setMock(HttpCalloutMock.class, new AnimalLocatorMock()); 
    }

以上終了です。笑
え、それだけ?と思うかもしれませんが、本来はMockクラスを使ってresponceを検証するんですが
あと返却値の確認かあと思うと省略してしまいました笑
(テストつまんないんだもん。。。)

て事で完了です。

Process Automation Specialistのスーパーバッチがなかなか着手できてないのでやらないと。。。
と思いつつ引き続き基礎を固ていく予定です笑


コメント