春にRestTemplateをモックする

1.はじめに

多くの場合、ある種のWeb要求を実行するアプリケーションがあります。この振る舞いをテストすることになると、私達はいくつかのhttps://medium.com/@davidh__23/testing-http-applications-with-a-few-ok-libraries-3092790f426d[options]をSpringアプリケーションと共に持っています。

  • このクイックチュートリアルでは、 RestTemplate ** を通じてのみ実行されるこのような呼び出しをモックする方法をいくつか紹介します。

人気のあるモッキングライブラリであるMockitoを使ってテストを始めます。それから、Spring Testを使用して、サーバーとのやり取りを定義するためのモックサーバーを作成するメカニズムを提供します。

2. Mockito を使う

__RestTemplate __altoをモックするためにMockitoを使用することができます。このアプローチでは、私たちのサービスをテストすることは他のhttps://www.baeldung.com/mockito-annotations[モッキングを含むテスト]と同じくらい簡単です。

HTTPを通して従業員の詳細を取得する単純な EmployeeService クラスがあるとします。

@Service
public class EmployeeService {

    @Autowired
    private RestTemplate restTemplate;

    public Employee getEmployee(String id) {
    ResponseEntity resp =
          restTemplate.getForEntity("http://localhost:8080/employee/" + id, Employee.class);

    return resp.getStatusCode() == HttpStatus.OK ? resp.getBody() : null;
    }
}

前のコードのテストを実装しましょう:____

@RunWith(MockitoJUnitRunner.class)
public class EmployeeServiceTest {

    @Mock
    private RestTemplate restTemplate;

    @InjectMocks
    private EmployeeService empService = new EmployeeService();

    @Test
    public void givenMockingIsDoneByMockito__whenGetIsCalled__shouldReturnMockedObject() {
        Employee emp = new Employee(“E001”, "Eric Simmons");
        Mockito
          .when(restTemplate.getForEntity(“http://localhost:8080/employee/E001”, Employee.class))
          .thenReturn(new ResponseEntity(emp, HttpStatus.OK));

        Employee employee = empService.getEmployee(id);
        Assert.assertEquals(emp, employee);
    }
}

上記のJUnitテストクラスでは、最初にMockitoに @ Mock アノテーションを使ってダミーの RestTemplate インスタンスを作成するよう依頼しました。

次に、 EmployeeService インスタンスに @ InjectMocks というアノテーションを付けてダミーインスタンスを挿入しました。

最後に、テストメソッドでは、https://www.baeldung.com/mockito-behavior[Mockitoのwhen/then support]を使用してモックの動作を定義しました。

3. Spring Testを使う

Spring Testモジュールには、 MockRestServiceServerという名前のモックサーバーが含まれています。** このアプローチでは、特定のリクエストが RestTemplate インスタンスを介してディスパッチされたときに特定のオブジェクトを返すようにサーバーを構成します。すべての期待に応えたかどうか

MockRestServiceServer は、実際には MockClientHttpRequestFactory を使用してHTTP API呼び出しをインターセプトすることによって機能します。私たちの設定に基づいて、それは期待されるリクエストと対応するレスポンスのリストを作成します。 RestTemplate インスタンスがAPIを呼び出すと、期待値の一覧で要求が検索され、対応する応答が返されます。

したがって、モックレスポンスを送信するために他のポートでHTTPサーバーを実行する必要がなくなります。

MockRestServiceServer を使用して、同じ getEmployee() サンプルの簡単なテストを作成しましょう。

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = SpringTestConfig.class)
public class EmployeeServiceMockRestServiceServerUnitTest {

    @Autowired
    private EmployeeService empService;
    @Autowired
    private RestTemplate restTemplate;

    private MockRestServiceServer mockServer;
    private ObjectMapper mapper = new ObjectMapper();

    @Before
    public void init() {
        mockServer = MockRestServiceServer.createServer(restTemplate);
    }

    @Test
    public void givenMockingIsDoneByMockRestServiceServer__whenGetIsCalled__thenReturnsMockedObject()() {
        Employee emp = new Employee("E001", "Eric Simmons");
        mockServer.expect(ExpectedCount.once(),
          requestTo(new URI("http://localhost:8080/employee/E001")))
          .andExpect(method(HttpMethod.GET))
          .andRespond(withStatus(HttpStatus.OK)
          .contentType(MediaType.APPLICATION__JSON)
          .body(mapper.writeValueAsString(emp))
        );

        Employee employee = empService.getEmployee(id);
        mockServer.verify();
        Assert.assertEquals(emp, employee);
    }
}

前のスニペットでは、 MockRestRequestMatchers および MockRestResponseCreators の静的メソッドを使用して、REST呼び出しに対する期待と応答を明確で読みやすい方法で定義しました。

import static org.springframework.test.web.client.match.MockRestRequestMatchers.** ;
import static org.springframework.test.web.client.response.MockRestResponseCreators.** ;

テストクラスの RestTemplate は、 EmployeeService クラスで使用されているのと同じインスタンスである必要があることに注意してください。これを確実にするために、春の設定でRestTemplate Beanを定義し、テストと実装の両方でインスタンスを自動配線しました。

@Bean
public RestTemplate restTemplate() {
    return new RestTemplate();
}

MockRestServiceServer を使用することは、私たちが統合テストを書いて外部HTTP呼び出しをモックするだけでいいときに非常に便利です。

4.まとめ

この短い記事では、単体テストを書いている間にHTTP経由で外部REST API呼び出しを偽装するためのいくつかの効果的なオプションについて説明しました。

上記の記事のソースコードはhttps://github.com/eugenp/tutorials/tree/master/spring-resttemplate[GitHubで利用可能]です。

前の投稿:Spring Security 5.1クライアントでの承認とトークン要求のカスタマイズ
次の投稿:java.util.Propertiesオブジェクトのマージ