Check out the full series of Questions Management tutorial here.
In the previous tutorial, we prepared all the necessary configurations to build an API to find question by id in the MongoDB database: a Question document object containing the information of a question, a QuestionRepository to manipulate with MongoDB, a QuestionController that defines APIs for the Core Question Service will start with “/question” 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 an API to find question by id, I would add a method to expose a GET request “/{id}” with id as the id of the question we are looking for:
1 2 3 4 |
@GetMapping("/{id}") public Mono<ResponseEntity<Question>> findQuestionById(@PathVariable(value = "id") String questionId) { } |
The steps to look up question by id include:
First, we also need to check whether the question we are looking for does exist or not based 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 |
questionRepository.findById(questionId) |
In case this question exists, we will return it using the map() method with the HTTP status code of 200:
1 2 |
questionRepository.findById(questionId) .map(question -> ResponseEntity.ok(question)) |
In case this question does not exist in the database, we will return the result of the HTTP status code is 404 Not Found.
1 2 3 |
questionRepository.findById(questionId) .map(question -> ResponseEntity.ok(question)) .defaultIfEmpty(ResponseEntity.notFound().build()); |
The entire contents of the findQuestionById() method will look like this:
1 2 3 4 5 6 |
@GetMapping("/{id}") public Mono<ResponseEntity<Question>> findQuestionById(@PathVariable(value = "id") String questionId) { return questionRepository.findById(questionId) .map(question -> ResponseEntity.ok(question)) .defaultIfEmpty(ResponseEntity.notFound().build()); } |
Here we have completed the construction of the API to find question by id for the Core Question Service, let’s test it.
Suppose the current in the database I have the following questions:
so when I request to find the question with id is 5ad5d9d651bd7a0aefa87fb3, the result will be:
Now we will add a new Unit Test for the code that we just added
In my last post, I created a new test class for QuestionController class called QuestionControllerTest, mock object for QuestionRepository, and injected this mock object into the QuestionController class, initializing mock objects each time I run a test case as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
package com.huongdanjava.questionservice; import org.junit.Before; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import com.huongdanjava.questionservice.repository.QuestionRepository; public class QuestionControllerTest { @Mock private QuestionRepository questionRepository; @InjectMocks private QuestionController questionController; @Before public void init() { MockitoAnnotations.initMocks(this); } } |
Now we will add two methods to test for the method of findQuestionById() of the QuestionController class as follows:
A method to test for the case there is an existing question base 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 testFindExistingQuestion() { // Create question document to return when using findById Question question = new Question(); question.setId("123"); question.setDescription("Test"); question.setCategoryId("123XYZ"); // Mock findById() method of QuestionRepository to return above question when(questionRepository.findById("123")).thenReturn(Mono.just(question)); // Call method Mono<ResponseEntity<Question>> update = questionController.findQuestionById("123"); ResponseEntity<Question> responseEntity = update.block(); // Assertions assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); Question responseQuestion = responseEntity.getBody(); assertEquals("Test", responseQuestion.getDescription()); assertEquals("123XYZ", responseQuestion.getCategoryId()); assertEquals("123", responseQuestion.getId()); } |
A method to test for the case there is non-existing question with passing id:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
@Test public void testFindNoExistingQuestion() { // Mock findById() method of QuestionRepository to return an empty Mono when(questionRepository.findById("123")).thenReturn(Mono.empty()); // Call method Mono<ResponseEntity<Question>> update = questionController.findQuestionById("123"); ResponseEntity<Question> 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.