Check out the full series of Questions Management tutorial here.
In the previous tutorial, we prepared all the necessary configurations for building the API to find a category by id like: a Category document object containing the information of a category, a CategoryRepository to manipulate with MongoDB, a CategoryController defines the APIs for Core Category Services that will start with “/category” and the connection information to the MongoDB server is configured in the application.properties file. Now, we are going to build this API!
To build the API to find category by id, I would add a method to expose a GET request “{id}” with id as the id of the category we are looking for:
1 2 3 4 |
@GetMapping("/{id}") public Mono<ResponseEntity<Category>> findCategoryById(@PathVariable(value = "id") String categoryId) { } |
The steps to find a category by id include:
First, we need to check that the category which we are searching is existing or not, depend on the id that the user is 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 return this category using the map() method with the HTTP status code of 200:
1 2 |
categoryRepository.findById(categoryId) .map(category -> ResponseEntity.ok(category)) |
In case this category does not exist in the database, we will return the result of HTTP status code is 404 Not Found.
1 2 3 |
categoryRepository.findById(categoryId) .map(category -> ResponseEntity.ok(category)) .defaultIfEmpty(ResponseEntity.notFound().build()); |
The entire contents of the findCategoryById() method will look like this:
1 2 3 4 5 6 |
@GetMapping("/{id}") public Mono<ResponseEntity<Category>> findCategoryById(@PathVariable(value = "id") String categoryId) { return categoryRepository.findById(categoryId) .map(category -> ResponseEntity.ok(category)) .defaultIfEmpty(ResponseEntity.notFound().build()); } |
Here we have completed the construction of the API to find category by id for the Core Category Service, let’s test it.
Suppose currently in the database I have the following categories:
then when I request to find a category with id is 5b297751366e2605cf3c0d3e:
The result will be:
Now we will add a new Unit Test for the code that 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 I’m going to add two methods to test the method findCategoryById() in the CategoryController class.
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 23 24 |
@Test public void testFindExistingCategory() { // 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)); // Call method Mono<ResponseEntity<Category>> update = categoryController.findCategoryById("123"); ResponseEntity<Category> responseEntity = update.block(); // Assertions assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); Category responseCategory = responseEntity.getBody(); assertEquals("ZXC", responseCategory.getName()); assertEquals("ABC", responseCategory.getCode()); assertEquals("123", responseCategory.getId()); } |
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 testFindNoExistingCategory() { // Mock findById() method of CategoryRepository to return an empty Mono when(categoryRepository.findById("123")).thenReturn(Mono.empty()); // Call method Mono<ResponseEntity<Category>> update = categoryController.findCategoryById("123"); ResponseEntity<Category> responseEntity = update.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.