【问题标题】:Spring Boot integration test. How to test the 'DELETE' method?Spring Boot 集成测试。如何测试“删除”方法?
【发布时间】:2021-12-13 16:04:20
【问题描述】:

我正在使用Spring Boot 2.5.6JUnit 4.13.2。我的任务是测试DELETE方法

我的 REST 控制器:

@RestController
public class DomainEndpoint {

    private final SomeService service;

    @DeleteMapping("/domain/{id}")
    public void delete(@PathVariable long id) {
        service.delete(id);
    }
}

我的测试:

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

    @Autowired
    TestRestTemplate template;

    @MockBean
    SomeService service;

    @Test
    public void delete() {
        String url = "/domain/123";
        ResponseEntity<?> resp = template.exchange(url, HttpMethod.DELETE, new HttpEntity<>(""), String.class);
        assertEquals(HttpStatus.NO_CONTENT, resp.getStatusCode());
    }
}

如您所见,我发现的测试“DELETE”方法的唯一解决方案是:

ResponseEntity<?> resp = template.exchange(url, HttpMethod.DELETE, new HttpEntity<>(""), String.class);

但是身体 new HttpEntity&lt;&gt;("") 和返回类型 String.class 的参数对我来说似乎很奇怪。我为什么要使用它们?我可以在不传递不必要参数的情况下更直接地做同样的事情吗?
另一方面,TestRestTemplate template 有一组简短易读的方法delete()。他们的问题 - 他们返回void,在这种情况下我无法检查响应状态代码。

主要问题是如何正确测试DELETE方法?

【问题讨论】:

    标签: java spring spring-boot rest junit


    【解决方案1】:

    而不是传入new HttpEntity&lt;&gt;("") HttpEntity 有一个特殊的类变量,您可以在这些情况下使用称为HttpEntity.EMPTY。您也可以使用 void 返回类型。

    ResponseEntity<Void> resp = template.exchange(url, HttpMethod.DELETE, HttpEntity.EMPTY, Void.class);
    

    【讨论】:

    • 谢谢,与我的示例相比,它更具可读性。
    【解决方案2】:

    两点你可以改进:

    1. 不提供请求实体——它被标记为@Nullable
    2. 使用Void.class 作为返回类型来表示您不期望任何响应正文
    ResponseEntity<Void> resp = restTemplate.exchange(url, HttpMethod.DELETE, null, Void.class);
    

    【讨论】:

    • 谢谢你的回答,这是一个更简化的例子,但null 让我害怕——它不是真的可读。你知道,有没有其他方法不需要不必要的参数,尤其是身体?
    【解决方案3】:

    其他人提供了不同的选项,但如果您想使用 delete 方法 - 它会在内部通过抛出运行时错误来处理 http 错误,如您所见 here。您可以使用 JUnit5 中的 assertDoesNotThrow 来检查 HttpClientErrorExceptionHttpServerErrorException

    【讨论】:

    • 感谢您的回答。但在那种情况下,我无法检查确切的状态 == 204(无内容)
    • @Shailendra AFAIK TestRestTemplate 不会像RestTemplate 那样抛出任何异常。
    • @slauth 你能发布 TestRestTemplate 的课程吗?由于您使用的是 RestTemplate 公开的类似方法,我假设它是扩展 RestTemplate 的东西,还是您开发的一些自定义实现
    • @Shailendra TestRestTemplateRestTemplate 的包装器,它在包装后的RestTemplate 上设置NoOpResponseErrorHandler
    【解决方案4】:

    在我看来,RestTemplate.delete 方法是可以使用的,返回类型为 void,但 2XX 以外的状态会抛出异常。

    【讨论】:

    • 感谢您的回答。但在那种情况下,我无法检查确切的状态 == 204(无内容)
    • @user3075118 AFAIK TestRestTemplate 不会像RestTemplate 那样抛出任何异常。
    猜你喜欢
    • 2020-02-25
    • 1970-01-01
    • 1970-01-01
    • 2015-08-20
    • 2020-04-24
    • 2017-10-27
    • 1970-01-01
    • 2022-12-09
    • 1970-01-01
    相关资源
    最近更新 更多