【问题标题】:How to use testRestTemplate for a post request with no request body如何将 testRestTemplate 用于没有请求正文的发布请求
【发布时间】:2019-04-06 16:47:15
【问题描述】:

我有一个休息端点如下:

@PostMapping(value = "/customers/{customerId}")
public SomeResponse manageCustomers(@PathVariable  String customerId){
...
}

此端点从一个系统中为给定的 customerId 挑选客户数据并将其保存在另一个系统中。因此,它不需要任何请求正文。

我需要为此编写一个集成测试。当我为此使用 testRestTemplate 时,我找不到一个足够好的方法可以将 requestEntity 作为空值传递。每当我这样做时,我都会收到一个异常说“uriTemplate 不能为空”。

我曾尝试使用'postForObject'、'exchange' 方法但不起作用。有什么想法吗?

下面是我的 IT:

@SpringBootTest(webEnvironmentSpringBootTest.WebEnvironment.RANDOM_PORT)
@DirtiesContext
@ActiveProfiles("test")
class CustomerIT extends Specification{

@LocalServerPort
private int port;

@Autowired
private TestRestTemplate restTemplate

def "should get customer from first system and save in second system"() {

    given:
    def customerUrl = new URI("http://localhost:" + port + "/customers/1234")
    def expected = new SomeObject(1)

    when:
    def someObject =
            restTemplate.postForEntity(customerUrl, null, SomeObject.class)

    then:
    someObject != null
    someObject == expected
}
}

【问题讨论】:

  • 如果expectedsecondSystemMockUrluriTemplatenull,我首先要弄清楚为什么会这样。您能否创建第二个 IT 来模仿我写的最小的 IT,而不需要所有额外的东西?即使您不存根 secondSystem,您也可能会遇到不同的异常?
  • 我删除了所有的wiremock东西并尝试再次运行它以查看它是否至少到达控制器但我仍然遇到uriTemplate为空的相同异常。如果您有什么想法,请告诉我,但无论如何感谢您的关注。
  • 或许您可以发布精简后的 IT?
  • 用最少的 IT 编辑了我的帖子。
  • 只需尝试几件事。 1) 删除 @Autowirednew restTemplate。 2) customerUrlURIString 和 3) 删除 @DirtiesContext - 甚至可能是 @ActiveProfiles("test")。我真的不指望这会有所作为,而只是把所有东西都去掉。也许看看你正在使用的任何测试框架的范围 - 我不熟悉它。非常牵强,但given: 范围可能在when: 范围中不可用

标签: spring-boot post uri integration-testing resttemplate


【解决方案1】:

使用postForEntity(url, null, ResponseType.class) 对我有用。

除了 responseType 之外,我的 postmapping 与您的相同。我以Map 为例

@PostMapping(value = "/customers/{customerId}")
public Map<String, String> manageCustomers(@PathVariable String customerId){
    return new HashMap<String, String>(){{ put("customerId", customerId); }};
}

测试以验证它是否有效

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

    @LocalServerPort
    private int port;

    private final TestRestTemplate testRestTemplate = new TestRestTemplate();

    @Test
    public void postEmptyBodyShouldReturn200OK() {
        String customerId = "123";
        ResponseEntity responseEntity = testRestTemplate
                .postForEntity(format("http://localhost:%s/ping/customers/%s", port, customerId), null, Map.class);
        assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
        assertThat(responseEntity.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_JSON_UTF8);
        assertThat(responseEntity.getBody()).isNotNull();
        assertThat(((LinkedHashMap) responseEntity.getBody()).size()).isEqualTo(1);
        assertThat(((LinkedHashMap) responseEntity.getBody()).get("customerId")).isEqualTo(customerId);
    }
}

在 maven 中运行这个测试

$ mvn -Dtest=CustomerControllerTest test

    (...removed unnecessary output...)

[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 4.137 s - in com.ins.example.demo.rest.CustomerControllerTest
10:04:54.683 [Thread-3] INFO  o.s.s.c.ThreadPoolTaskExecutor - Shutting down ExecutorService 'applicationTaskExecutor'
[INFO] 
[INFO] Results:
[INFO] 
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  6.940 s
[INFO] Finished at: 2019-04-07T10:04:55+02:00
[INFO] ------------------------------------------------------------------------

【讨论】:

  • 我仍然遇到同样的异常。我已经用我的集成测试更新了我的问题。你能看一下吗?
猜你喜欢
  • 2016-06-15
  • 2021-02-12
  • 2018-08-18
  • 1970-01-01
  • 2017-08-31
  • 2020-12-13
  • 1970-01-01
  • 2018-12-11
相关资源
最近更新 更多