Spring Boot 集成测试。如何测试“删除”方法?
Posted
技术标签:
【中文标题】Spring Boot 集成测试。如何测试“删除”方法?【英文标题】:Spring Boot integration test. How to test the 'DELETE' method? 【发布时间】:2021-12-13 16:04:20 【问题描述】:我正在使用Spring Boot 2.5.6
和JUnit 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<>("")
和返回类型 String.class
的参数对我来说似乎很奇怪。我为什么要使用它们?我可以在不传递不必要参数的情况下更直接地做同样的事情吗?
另一方面,TestRestTemplate template
有一组简短易读的方法delete()
。他们的问题 - 他们返回void
,在这种情况下我无法检查响应状态代码。
主要问题是如何正确测试DELETE
方法?
【问题讨论】:
【参考方案1】:而不是传入new HttpEntity<>("")
HttpEntity
有一个特殊的类变量,您可以在这些情况下使用称为HttpEntity.EMPTY
。您也可以使用 void 返回类型。
ResponseEntity<Void> resp = template.exchange(url, HttpMethod.DELETE, HttpEntity.EMPTY, Void.class);
【讨论】:
谢谢,与我的示例相比,它更具可读性。【参考方案2】:两点你可以改进:
-
不提供请求实体——它被标记为
@Nullable
使用Void.class
作为返回类型来表示您不期望任何响应正文
ResponseEntity<Void> resp = restTemplate.exchange(url, HttpMethod.DELETE, null, Void.class);
【讨论】:
谢谢你的回答,这是一个更简化的例子,但null
让我害怕——它不是真的可读。你知道,有没有其他方法不需要不必要的参数,尤其是身体?【参考方案3】:
其他人提供了不同的选项,但如果您想使用 delete
方法 - 它会在内部通过抛出运行时错误来处理 http 错误,如您所见 here。您可以使用 JUnit5 中的 assertDoesNotThrow
来检查 HttpClientErrorException
或 HttpServerErrorException
【讨论】:
感谢您的回答。但在那种情况下,我无法检查确切的状态 == 204(无内容) @Shailendra AFAIKTestRestTemplate
不会像RestTemplate
那样抛出任何异常。
@slauth 你能发布 TestRestTemplate 的课程吗?由于您使用的是 RestTemplate 公开的类似方法,我假设它是扩展 RestTemplate 的东西,还是您开发的一些自定义实现
@Shailendra TestRestTemplate 是RestTemplate
的包装器,它在包装后的RestTemplate
上设置NoOpResponseErrorHandler。【参考方案4】:
在我看来,RestTemplate.delete 方法是可以使用的,返回类型为 void,但 2XX 以外的状态会抛出异常。
【讨论】:
感谢您的回答。但在那种情况下,我无法检查确切的状态 == 204(无内容) @user3075118 AFAIKTestRestTemplate
不会像RestTemplate
那样抛出任何异常。以上是关于Spring Boot 集成测试。如何测试“删除”方法?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Spring Boot 集成测试中使用嵌入式 MongoDB
如何使用带有 gradle 的多个嵌入式服务器运行 spring-boot 集成测试
如何在 Spring Boot 2.2.0 的集成测试中禁用安全性?