Spring Boot:如何为删除其余模板编写单元测试用例
Posted
技术标签:
【中文标题】Spring Boot:如何为删除其余模板编写单元测试用例【英文标题】:Spring boot : How to write unit test case for delete rest template 【发布时间】:2020-11-21 20:51:14 【问题描述】:我正在尝试为 HttpHandler 类编写单元测试用例,该类具有用于删除的其余模板调用。我已经创建了一个用户控制器类来进行 resttemplate 调用,以便在 HttpHandler 类中测试sendDelete
的功能。有人可以帮我理解在HtttpHandler
类中为sendDelete
方法编写单元测试用例的正确方法是什么吗?
我有一个类 HttpHandler。它有一个函数sendDelete
,它调用resttemplate.exchange
method
@Service
public class HttpHandler
public <T,R> ResponseEntity<Void> sendDelete(String url, HttpHeaders httpHeaders, R requestBody, Class<T> responseClass)
//create an instance of rest template
RestTemplate restTemplate = new RestTemplate();
HttpEntity<R> entity = new HttpEntity<R>(requestBody, httpHeaders);
logger.info("DELETE request to " + url + " with body: " + JsonUtil.jsonizeExcludeNulls(requestBody));
//make an HTTP DELETE request with headers
ResponseEntity<Void> response = restTemplate.exchange(url, HttpMethod.DELETE, entity, Void.class);
logger.info("DELETE" + url + ": " + JsonUtil.jsonize(response));
return response;
我正在使用junit5。下面是上面类中 sendDelete 方法的单元测试用例:
@LocalServerPort
private int port;
private String baseUrl;
@Autowired
private HttpHandler httpHandler;
@BeforeEach
public void setBaseUrl()
this.baseUrl = "http://localhost:"+ port + "/users";
@Test
public void testSuccessDeleteUserById() throws Exception
this.baseUrl = baseUrl + "/1";
//create headers
HttpHeaders httpHeaders = new HttpHeaders();
//set content type
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
httpHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
//make an HTTP DELETE request with headers
ResponseEntity<Void> actual = httpHandler.sendDelete(baseUrl, httpHeaders, null, Void.class);
assertEquals(404, actual.getStatusCodeValue());
下面是用户控制器类
@RestController
public class UserController
@DeleteMapping("/users/userId")
public ResponseEntity<Void> deleteUser(@PathVariable("userId") int userId)
return new ResponseEntity<Void>(HttpStatus.NOT_FOUND);
感谢您的宝贵时间!
【问题讨论】:
【参考方案1】:有两种方法可以做到。
模拟 RestTemplate。为此,首先,您必须使 RestTemplate 成为一个字段,并通过构造函数(或任何其他方式)将其注入。这允许您注入模拟对象。然后,剩下的就是简单明了的 mocking。
您可以使用MockWebServer。这样你就不需要改变任何东西。它只是您的方法将请求发送到的 Web 服务器。方法调用完成后,您可以访问记录的请求并进行一些验证。
这是一个粗略的例子。如果您将进行大量此类测试,那么您可以将 Web 服务器初始化移至 @BeforeEach
方法,并将销毁移至 @AfterEach
方法。
public class HttpHandlerTest
private final HttpHandler handler = new HttpHandler();
@Test
@SneakyThrows
public void testDelete()
MockWebServer mockWebServer = new MockWebServer();
mockWebServer.start(9889);
mockWebServer.enqueue(
new MockResponse().setResponseCode(200)
);
String url = "http://localhost:9889";
Hello hello = new Hello("hello world");
final ResponseEntity<Void> entity = handler.sendDelete(url, null, hello, Hello.class);
assertNotNull(entity);
assertEquals(200, entity.getStatusCode().value());
final RecordedRequest recordedRequest = mockWebServer.takeRequest();
assertEquals("DELETE", recordedRequest.getMethod());
mockWebServer.close();
// just an example class to use as a payload
class Hello
String text;
public Hello()
public Hello(String text)
this.text = text;
public String getText()
return text;
public void setText(String text)
this.text = text;
注意。即使您不会选择第一种解决方案,我还是建议您放弃为每个请求初始化 RestTemplate。你最好改用 WebClient 。如果这样做,第一个解决方案将不再有效,而第二个解决方案将保持不变。
【讨论】:
感谢您的宝贵时间和所有帮助。 @ 987654325@ 请您帮我理解这示例的确切含义。再次感谢! 基本上,每次发出请求时不要初始化RestTemplate。把它变成一个 bean 并注入到你的类中。 好的,谢谢!!可以在每个请求上初始化 HttpHeaders 吗?我应该创建一个 bean 并注入它吗? 标头特定于请求,所以不,您不需要这样做。 好的,谢谢你分享mockWebServer
。我不知道。以上是关于Spring Boot:如何为删除其余模板编写单元测试用例的主要内容,如果未能解决你的问题,请参考以下文章
使用 Spring Security 进行 Spring Boot 单元测试