Check out the full series of Questions Management tutorial here.
In the previous tutorial, we prepared all the information we needed to create the category deletion API: a Category document object containing information about a category, a CategoryRepository to manipulate MongoDB, a CategoryController defines the APIs of the Core Category Service that will start with “/category” and the connection information to the MongoDB server is configured in the application.properties file. Now, we will proceed to build API to delete a category.
To create a category deletion API, we will add a new method to expose a DELETE request “{id}” with the id of the category we want to delete:
1 2 3 |
@DeleteMapping("/{id}") public Mono<ResponseEntity<Void>> deleteCategory(@PathVariable(value = "id") String categoryId) { } |
You can see the post Binding variables in URI request to method’s parameters using @PathVariable annotation in Spring MVC to better understand the variable id in the above request URL.
The steps to remove a category include:
First, we need to check that the category that we want to delete does exist or not based on the id that the user passing.
Spring Data MongoDB Reactive has provided us with a way to search by id so we just need to call it.
1 |
categoryRepository.findById(categoryId); |
In case this category exists, we will delete it and return the HTTP status code to 200 OK.
1 2 3 |
categoryRepository.findById(categoryId) .flatMap(existingCategory -> categoryRepository.delete(existingCategory) .then(Mono.just(new ResponseEntity<Void>(HttpStatus.OK)))) |
If it does not exist, return the HTTP status code of 404 Not Found.
1 2 3 4 |
return categoryRepository.findById(categoryId) .flatMap(existingCategory -> categoryRepository.delete(existingCategory) .then(Mono.just(new ResponseEntity<Void>(HttpStatus.OK)))) .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND)); |
The entire contents of the deleteCategory() method will now look like this:
1 2 3 4 5 6 7 |
@DeleteMapping("/{id}") public Mono<ResponseEntity<Void>> deleteCategory(@PathVariable(value = "id") String categoryId) { return categoryRepository.findById(categoryId) .flatMap(existingCategory -> categoryRepository.delete(existingCategory) .then(Mono.just(new ResponseEntity<Void>(HttpStatus.OK)))) .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND)); } |
At this point, we have completed the building API deleting category for the Core Category Service, let’s test it.
Suppose, currently in the database I have the following categories:
so, when I request to delete the category with id is 5b22fdcc3ec1ae0367a68bf1:
The result will be:
The last thing we need to do is add a new Unit Test to the code we just added.
In the previous tutorial, I created a class test for CategoryController called CategoryControllerTest, a Mock object for CategoryRepository, and injected this Mock object into the CategoryController class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
package com.huongdanjava.categoryservice; import org.mockito.InjectMocks; import org.mockito.Mock; import com.huongdanjava.categoryservice.repository.CategoryRepository; public class CategoryControllerTest { @Mock private CategoryRepository categoryRepository; @InjectMocks private CategoryController categoryController; } |
Initializing the mock every time I run a test case:
1 2 3 4 |
@Before public void init() { MockitoAnnotations.initMocks(this); } |
Now we will add two methods to test the deleteCategory() method of the CategoryController class as follows:
A method to test if there is a category based on passing id:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
@Test public void testDeleteExistingCategory() { // Create category document to return when using findById Category category = new Category(); category.setId("123"); category.setCode("ABC"); category.setName("ZXC"); // Mock findById() method of CategoryRepository to return above category when(categoryRepository.findById("123")).thenReturn(Mono.just(category)); // Mock delete() method of CategoryRepository when(categoryRepository.delete(category)).thenReturn(Mono.empty()); // Call method Mono<ResponseEntity<Void>> delete = categoryController.deleteCategory("123"); ResponseEntity<Void> responseEntity = delete.block(); // Assertions assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); } |
A method to test for the absence of category based on passing id:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
@Test public void testDeleteNoExistingCategory() { // Mock findById() method of CategoryRepository to return an empty Mono when(categoryRepository.findById("123")).thenReturn(Mono.empty()); // Call method Mono<ResponseEntity<Void>> delete = categoryController.deleteCategory("123"); ResponseEntity<Void> responseEntity = delete.block(); // Assertions assertEquals(HttpStatus.NOT_FOUND, responseEntity.getStatusCode()); } |
Run “Maven test” in STS or “mvn test” with Apache Maven, you will not see any errors.