Reputation: 3454
I'm using Spring Boot 2.5.6
and JUnit 4.13.2
. My task is to test the DELETE
method
My REST controller:
@RestController
public class DomainEndpoint {
private final SomeService service;
@DeleteMapping("/domain/{id}")
public void delete(@PathVariable long id) {
service.delete(id);
}
}
My test:
@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());
}
}
As you can see, the only solution for testing the 'DELETE' method, which I found, is:
ResponseEntity<?> resp = template.exchange(url, HttpMethod.DELETE, new HttpEntity<>(""), String.class);
But params for body new HttpEntity<>("")
and for return type String.class
seem strange to me. Why should I use them? Can I do the same more straightway without passing unnecessary parameters?
On the other hand, TestRestTemplate template
has a set of short and readable methods delete()
. The problem with them - they return void
and I can't check the response status code in this case.
The main question is how to test DELETE
methods correctly?
Upvotes: 0
Views: 4153
Reputation: 515
If you are using Kotin, feel free to use this extension methods :)
/**
* Extension for using PUT (not provided by default)
*/
inline fun <RQ : Any, reified RP : Any> TestRestTemplate.putForEntity(url: String, payload: RQ): ResponseEntity<RP> =
this.exchange(url, PUT, HttpEntity(payload))
/**
* Extension for [TestRestTemplate] DELETE (not provided by default, whyever)
*/
inline fun <reified RQ : Any> TestRestTemplate.deleteForEntity(url: String): ResponseEntity<RQ> =
this.exchange(url, DELETE)
/**
* Extension for [TestRestTemplate] DELETE with payload (not provided by default, whyever)
*/
inline fun <reified RQ : Any, reified RP : Any> TestRestTemplate.deleteForEntity(
url: String,
payload: RQ
): ResponseEntity<RP> = this.exchange(url, DELETE, HttpEntity(payload))
Upvotes: 0
Reputation: 131
In my opinion RestTemplate.delete method is the one to use, return type is void but status other than 2XX will throw an exception.
Upvotes: 0
Reputation: 9102
Others have given different options but if you want to use the the delete
method - it internally handles the http error by throwing runtime error as you can see here. You can check for HttpClientErrorException
or HttpServerErrorException
by using assertDoesNotThrow
from JUnit5
Upvotes: 0
Reputation: 2733
Instead of passing in new HttpEntity<>("")
HttpEntity
has a special class variable you can use called HttpEntity.EMPTY
for these situations. You can also use a return type of void.
ResponseEntity<Void> resp = template.exchange(url, HttpMethod.DELETE, HttpEntity.EMPTY, Void.class);
Upvotes: 4
Reputation: 3178
Two things you could improve:
@Nullable
Void.class
as return type to express that you don't expect any response bodyResponseEntity<Void> resp = restTemplate.exchange(url, HttpMethod.DELETE, null, Void.class);
Upvotes: 1