模拟休息模板进行单元测试 [英] mock rest template for unit test

查看:75
本文介绍了模拟休息模板进行单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在Spring Boot中模拟RestTemplate,在其中我正在方法中进行REST调用.为了测试我正在创建的微服务的控制器, 我想在微服务的控制器中测试方法.

I want to mock a RestTemplate in Spring Boot, where I'm making a REST call within a method. To test the controller of the microservice I'm creating, I want to test methods inside the controller of my micro service.

例如:

@GetMapping(value = "/getMasterDataView", produces = { MediaType.APPLICATION_JSON_VALUE })
@CrossOrigin(origins = { "http://192.1**********" }, maxAge = 3000)
public ResponseEntity<MasterDataViewDTO> getMasterDataView() throws IOException {

    final String uri = "http://localhost:8089/*********";

    RestTemplate restTemplate = new RestTemplate();
    MasterDataViewDTO masterDataViewDTO = restTemplate.getForObject(uri, MasterDataViewDTO.class);

    return new ResponseEntity<>(masterDataViewDTO, HttpStatus.OK);

}

如何使用模拟功能对此进行测试?

how to I test this using mocking?

这是我到目前为止所拥有的:

This is what I have so far:

@Test
    public void testgetMasterDataView() throws IOException {

    MasterDataViewDTO masterDataViewDTO= mock(MasterDataViewDTO.class);
    //String uri = "http://localhost:8089/*********"; 

    Mockito.when(restTemplate.getForObject(Mockito.anyString(),ArgumentMatchers.any(Class.class))).thenReturn(masterDataViewDTO);

    assertEquals("OK",inquiryController.getMasterDataView().getStatusCode());        
}

运行模拟程序时出现错误,方法getMasterDataView()被调用,并且其中的REST调用也被调用,并引发错误.如何编写测试,以便不调用REST端点?如果可能的话,我想用Mockito做到这一点.

I am getting an error when I'm running the mock, the method getMasterDataView() is getting called and the REST call within it is also getting called and is throwing an error. How can I write my test so that the REST endpoint is not called? If it's possible, I'd like to do this with Mockito.

推荐答案

在开始编写测试之前,应该对代码进行一些更改.首先,如果提取RestTemplate并为其创建一个单独的bean,然后将其注入到控制器中,将会容易得多.

Before you start writing a test, you should change your code a bit. First of all, it would be a lot easier if you extracted that RestTemplate, and created a separate bean for it which you would inject within your controller.

为此,请在@Configuration类或您的主类中添加以下内容:

To do that, add something like this within a @Configuration class or within your main class:

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

此外,您还必须从控制器中移除new RestTemplate(),并自动进行布线,例如:

Additionally, you have to remove the new RestTemplate() from your controller, and autowire it in stead, for example:

@Autowired
private RestTemplate restTemplate;

现在您已经完成了此操作,在测试中注入模拟RestTemplate会容易得多.

Now that you've done that, it's going to be a lot easier to inject a mock RestTemplate within your tests.

要进行测试,您有两种选择:

For your testing, you have two options:

  1. 使用模拟框架(例如Mockito)模拟RestTemplate以及您尝试访问的所有方法
  2. 或者您可以使用MockRestServiceServer,它使您可以编写测试来验证URL是否被正确调用,请求是否匹配等等.
  1. Either mock RestTemplate and all the methods you are trying to access, using a mocking framework (eg. Mockito)
  2. Or you can use MockRestServiceServer, which allows you to write tests that verify if the URLs are properly called, the request matches, and so on.

使用Mockito测试

要使用Mockito模拟RestTemplate,您必须确保在测试中添加以下注释:

Testing with Mockito

To mock your RestTemplate with Mockito, you have to make sure that you add the following annotation to your tests:

@RunWith(MockitoJUnitRunner.class)

之后,您可以执行以下操作:

After that, you can do this:

@InjectMocks
private MyController controller;
@Mock
private RestTemplate restTemplate;

现在您可以像这样调整测试:

And now you can adjust your tests like this:

@Test
public void testgetMasterDataView() throws IOException {
    MasterDataViewDTO dto = new MasterDataViewDTO();
    when(restTemplate.getForObject("http://localhost:8089/*********", MasterDataViewDTO.class)).thenReturn(dto);
    ResponseEntity<MasterDataViewDTO> response = controller.getMasterDataView();
    assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
    assertThat(response.getBody()).isEqualTo(dto);
}

您可以像在测试中一样模拟DTO,但不必这样做,而且我认为这样做没有任何好处.您要做的只是模拟restTemplate.getForObject(..)调用.

You could mock the DTO as you did within your test, but you don't have to, and I don't think there's any benefit from doing so. What you do have to mock is the restTemplate.getForObject(..) call.

另一种方法是使用MockRestServiceServer.为此,您必须在测试中使用以下注释:

Another approach is to use MockRestServiceServer. To do that, you have to use the following annotations for your test:

@RunWith(SpringRunner.class)
@RestClientTest

然后您必须自动连接控制器和MockRestServiceServer,例如:

And then you'll have to autowire your controller and MockRestServiceServer, for example:

@Autowired
private MyController controller;
@Autowired
private MockRestServiceServer server;

现在您可以编写如下测试:

And now you can write tests like this:

@Test
public void testgetMasterDataView() throws IOException {
    server
        .expect(once(), requestTo("http://localhost:8089/*********"))
        .andExpect(method(HttpMethod.GET))
        .andRespond(withSuccess(new ClassPathResource("my-mocked-result.json"), MediaType.APPLICATION_JSON));
    ResponseEntity<MasterDataViewDTO> response = controller.getMasterDataView();
    assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
    // TODO: Write assertions to see if the DTO matches the JSON structure
}

除了测试您的实际REST调用是否匹配之外,这还允许您测试JSON到DTO是否也能正常工作.

In addition to testing that your actual REST call matches, this also allows you to test if your JSON-to-DTO works as well.

这篇关于模拟休息模板进行单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆