如何在Java Spring中模拟RestTemplate?

c23*_*878 17 java unit-testing spring-mvc mockito

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);
    }
Run Code Online (Sandbox Code Playgroud)

我试图测试一个包含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;
    }
}
Run Code Online (Sandbox Code Playgroud)

Jos*_*nez 21

问题在于,isEnabled您正在创建一个新的RestTemplate.出于两个原因这是错误的,一个是你不能模拟它,因为你正在创建一个新的,第二个是避免每个请求创建新对象.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;
    }
}
Run Code Online (Sandbox Code Playgroud)

既然您的RestTemplate已成为类成员,您现在可以通过以下两种方式之一正确模拟.一,使用@InjectMock,或使用您从测试中调用的setter方法注入它.

由于您在代码中使用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);
    }
Run Code Online (Sandbox Code Playgroud)

请注意,我做了一些更改.首先,我删除了new RestTemplate()new Service().你应该让mockito为你创造这些.通过对它们进行注释@Mock,@Spy您将确保Mockito将为您创建它们,更重要的是,它们会将嘲讽注入您的service对象中.


Kei*_*ith 8

Spring MVC的测试框架MockRestServiceServer为单元测试RESTful服务代码提供了类.

这是一个关于它的使用的教程.