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で利用可能]です。