Check out the full series of Questions Management tutorial here.
Before we go into building the first API for the Core Question Service, we need to prepare the following:
First, we need to create a new QuestionRepository interface extends from the ReactiveMongoRepository interface to manipulate with the MongoDB database.
The contents of the QuestionRepository interface will look like this:
1 2 3 4 5 6 7 8 9 |
package com.huongdanjava.questionservice.repository; import org.springframework.data.mongodb.repository.ReactiveMongoRepository; import com.huongdanjava.questionservice.document.Question; public interface QuestionRepository extends ReactiveMongoRepository<Question, String> { } |
with Question document object:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
package com.huongdanjava.questionservice.document; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; import lombok.Data; @Data @Document public class Question { @Id private String id; private String description; private String categoryId; } |
You can see more the tutorial Reactive REST APIs with Spring Data MongoDB Reactive and Spring WebFlux for more information.
Next we will configure the connection to the MongoDB server.
Currently I am using MongoDB server without authentication mode so I just declare the following in application.properties file:
1 |
spring.data.mongodb.uri=mongodb://localhost:27017/qm |
I will run this service using port 8081, so I will add the server.port property in the application.properties file as follows:
1 |
server.port=8081 |
OK, everything is ready, now we will go to the main part of this tutorial!
I will create a controller named QuestionController with the following content:
1 2 3 4 5 6 7 8 9 10 |
package com.huongdanjava.questionservice; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/question") public class QuestionController { } |
With this declaration, I expose the APIs to the Core Question Service with the request URL starting with “/question”.
To work with MongoDB server, we need to inject QuestionRepository into QuestionController class as below:
1 2 |
@Autowired private QuestionRepository questionRepository; |
To build the API for adding a new question, I will add a new method to expose a POST request “/add” with the data in the body as a Question document object:
1 2 3 |
@PostMapping("/add") public Mono<Question> createQuestion(@RequestBody Question question) { } |
Because Spring MongoDB Reactive has provided us with the save() method to save the data to MongoDB, we just need to call this method:
1 2 3 4 |
@PostMapping("/add") public Mono<Question> createQuestion(@RequestBody Question question) { return questionRepository.save(question); } |
Now that we’ve finished building the API for adding a new question for the Core Question Service, let’s test it out.
The last thing we need to do is add a new Unit Test to the code we just added.
I will create a new class called QuestionControllerTest located in the src/test/java package to test the QuestionController class.
QuestionRepository mock class :
1 2 3 4 5 6 7 8 9 10 11 12 |
package com.huongdanjava.questionservice; import org.mockito.Mock; import com.huongdanjava.questionservice.repository.QuestionRepository; public class QuestionControllerTest { @Mock private QuestionRepository questionRepository; } |
Inject the QuestionRepository’s mock object into the QuestionController class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
package com.huongdanjava.questionservice; import org.mockito.InjectMocks; import org.mockito.Mock; import com.huongdanjava.questionservice.repository.QuestionRepository; public class QuestionControllerTest { @Mock private QuestionRepository questionRepository; @InjectMocks private QuestionController questionController; } |
To use mock objects, we have to initialize them one by one so we will add a method with the JUnit @Before annotation as follows:
1 2 3 4 |
@Before public void init() { MockitoAnnotations.initMocks(this); } |
The code to test the createQuestion() method is 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 |
public void testCreateQuestion() { // Create document need to insert into MongoDB Question question = new Question(); question.setDescription("Test"); question.setCategoryId("123XYZ"); // The result should be the same with additional id field Question result = question; result.setId("123"); // Mock save() method of QuestionRepository when(questionRepository.save(question)).thenReturn(Mono.just(result)); // Call method Mono<Question> createdQuestionAsMono = questionController.createQuestion(question); Question createdQuestion = createdQuestionAsMono.block(); // Assertions assertEquals("Test", createdQuestion.getDescription()); assertEquals("123XYZ", createdQuestion.getCategoryId()); assertEquals("123", createdQuestion.getId()); } |
Run “Maven test” in STS or “mvn test” with Apache Maven, you will not see any errors.