在Spring集成测试中模拟RestTemplateBuilder和RestTemplate [英] Mocking RestTemplateBuilder and RestTemplate in Spring integration test

查看:333
本文介绍了在Spring集成测试中模拟RestTemplateBuilder和RestTemplate的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个REST资源,它注入一个 RestTemplateBuilder 来构建一个 RestTemplate

I have a REST resource that gets a RestTemplateBuilder injected to build a RestTemplate:

public MyClass(final RestTemplateBuilder restTemplateBuilder) {
    this.restTemplate = restTemplateBuilder.build();
}

我想测试那个班级。我需要模拟 RestTemplate 对其他服务的调用:

I would like to test that class. I need to mock the calls the RestTemplate makes to another service:

request = restTemplate.getForEntity(uri, String.class);

我在我的IT中试过这个:

I tried this in my IT:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class MyIT {

@Autowired
private TestRestTemplate testRestTemplate;
@MockBean
private RestTemplateBuilder restTemplateBuilder;
@Mock
private RestTemplate restTemplate;

@Test
public void shouldntFail() throws IOException {

    ResponseEntity<String> responseEntity = new ResponseEntity<>(HttpStatus.NOT_FOUND);
    when(restTemplateBuilder.build()).thenReturn(restTemplate);
    when(restTemplate.getForEntity(any(URI.class), any(Class.class))).thenReturn(responseEntity);
...
ResponseEntity<String> response = testRestTemplate.postForEntity("/endpoint", request, String.class);
  ...
}
}

当我运行时测试,我得到以下异常:

When I run the test, I get the following exception:

java.lang.IllegalStateException: Failed to load ApplicationContext
...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.test.web.client.TestRestTemplate': Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: RestTemplate must not be null

如何正确执行此操作?

How do I do this correctly?

推荐答案

您的问题是执行的顺序。在您有机会在 @Test 中设置之前,将创建包含 MockBean 的上下文。解决方案是提供一个 RestTemplateBuilder ,当它插入上下文时已经完全设置。你可以这样做。

Your problem is the order of execution. The context is created containing your MockBean before you have a chance to set it up in your @Test. The solution is to provide a RestTemplateBuilder that's already fully setup when it's inserted into the context. You can do that like this.

将以下内容添加到 @SpringBootTest 注释中。其中 TestApplication 是您的Spring Boot应用程序类。

Add the following to your @SpringBootTest annotation. Where TestApplication is your Spring Boot application class.

classes = {TestApplication.class, MyIT.ContextConfiguration.class},

修改你的类成员,删除你的restTemplate和restTemplateBuilder 。

Modify your class members thus, deleting your restTemplate and restTemplateBuilder.

@Autowired
private TestRestTemplate testRestTemplate;

MyIT 中添加静态内部类class:

Add a static inner class to your MyIT class:

@Configuration
static class ContextConfiguration {
  @Bean
  public RestTemplateBuilder restTemplateBuilder() {

    RestTemplateBuilder rtb = mock(RestTemplateBuilder.class);
    RestTemplate restTemplate = mock(RestTemplate.class);

    when(rtb.build()).thenReturn(restTemplate);
    return rtb;
  }
}

在测试中,修改 RestTemplate 模拟做你想做的事:

In your tests, modify the RestTemplate mock to do whatever you want:

@Test
public void someTest() {

  when(testRestTemplate.getRestTemplate().getForEntity(...
}

这篇关于在Spring集成测试中模拟RestTemplateBuilder和RestTemplate的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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