web-dev-qa-db-ja.com

Java SpringでRestTemplateをモックする方法は?

public class ServiceTest {
    @Mock
    RestTemplate restTemplate = new RestTemplate();
    @InjectMocks
    Service service = new Service();
    ResponseEntity responseEntity = mock(ResponseEntity.class);

    @Test
    public void test() throws Exception {
        Mockito.when(restTemplate.getForEntity(
                Mockito.anyString(),
                Matchers.any(Class.class)
                ))
                .thenReturn(responseEntity);
        boolean res = service.isEnabled("something");
        Assert.assertEquals(res, false);
    }

Restclientを含むサービスの簡単なテストを試みました。 RestTemplateを正常にモックしていないようです。コードはモックデータではなく実際のデータを取得するようです。誰でもこれで私を助けることができます。

サービス自体は次のようになります。

public class Service{
    public boolean isEnabled(String xxx) {
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> response = restTemplate.getForEntity("someurl",String.class);
        if(...)return true;
        return false;
    }
}
15
c2340878

問題は、isEnabledで新しいRestTemplateを作成していることです。これは2つの理由で間違っています。1つは、新しいものを作成しているため、それをモックできないことです。2つ目は、リクエストごとに新しいオブジェクトを作成しないことです。 RestTemplateはスレッドセーフであるため、サービスクラスメンバーになり、多くのスレッドで使用されます。

サービスクラスを次のように変更します。

_public class Service{

    RestTemplate restTemplate = new RestTemplate();

    public boolean isEnabled(String xxx) {
        ResponseEntity<String> response = restTemplate.getForEntity("someurl",String.class);
        if(...)return true;
        return false;
    }
}
_

RestTemplateがクラスメンバーになったので、次の2つの方法のいずれかを使用して適切にモックできます。 1つは、_@InjectMock_を使用して挿入するか、テストから呼び出すセッターメソッドを使用します。

コードでInjectMockを使用しているので、それを使用できます。

_@RunWith(MockitoJUnitRunner.class) 
public class ServiceTest {
    @Mock
    RestTemplate restTemplate;
    @InjectMocks
    @Spy
    Service service;
    ResponseEntity responseEntity = mock(ResponseEntity.class);

    @Test
    public void test() throws Exception {
        Mockito.when(restTemplate.getForEntity(
                Mockito.anyString(),
                ArgumentMatchers.any(Class.class)
                ))
                .thenReturn(responseEntity);
        boolean res = service.isEnabled("something");
        Assert.assertEquals(res, false);
    }
_

いくつかの変更を加えたことに注意してください。最初に、new RestTemplate()new Service()を削除しました。 mockitoにそれらを作成させる必要があります。それらに_@Mock_および_@Spy_アノテーションを付けることで、Mockitoがそれらを作成し、さらに重要なことに、モックをserviceオブジェクトに挿入するようにします。

19
Jose Martinez

Spring MVCのテストフレームワークは、RESTfulサービスコードを単体テストするためのクラス MockRestServiceServer を提供しています。

ここに tutorial が使用されています。

8
Keith

@Autowiredを使用する場合、MockRestServiceServerを使用できます。以下はサンプルです。

@Service
public class Service{
    @Autowired
    private RestTemplate restTemplate;

    public boolean isEnabled(String xxx) {
        ResponseEntity<String> response = restTemplate.getForEntity("someurl",String.class);
        if(...)return true;
        return false;
    }
}

@Serviceは、オブジェクトを自動的に作成するために@Autowiredを使用する必要があります。

0
hiroyukik