Xem toàn bộ series bài viết hướng dẫn xây dựng ứng dụng Questions Management tại đây.
Trước khi đi vào xây dựng API đầu tiên cho Core Question Service, chúng ta cần chuẩn bị một số thứ như sau:
Đầu tiên là chúng ta cần tạo mới một interface QuestionRepository extends từ interface ReactiveMongoRepository để thao tác với MongoDB database.
Nội dung của interface QuestionRepository sẽ như sau:
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> { } |
với đối tượng document Question:
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; } |
Các bạn có thể xem thêm bài viết Reactive REST APIs với Spring Data MongoDB Reactive và Spring WebFlux để tham khảo thêm nhé!
Tiếp theo mình sẽ cấu hình phần kết nối tới MongoDB server.
Hiện tại mình đang sử dụng MongoDB server không phải là authentication mode nên mình chỉ cần khai báo như sau trong tập tin application.properties:
1 |
spring.data.mongodb.uri=mongodb://localhost:27017/qm |
Mình sẽ chạy service này sử dụng port 8081 nên mình sẽ thêm property server.port trong tập tin application.properties như sau:
1 |
server.port=8081 |
OK, mọi thứ chuẩn bị đã xong, bây giờ chúng ta sẽ đi vào phần chính của bài viết này các bạn nhé!
Mình sẽ tạo mới một controller tên là QuestionController với nội dung như sau:
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 { } |
Với khai báo trên, mình đã expose các API cho Core Question Service với request URL bắt đầu là “/question”.
Để thao tác với MongoDB server, chúng ta cần inject QuestionRepository vào class QuestionController như sau:
1 2 |
@Autowired private QuestionRepository questionRepository; |
Để xây dựng API thêm mới question, mình sẽ thêm mới một method để expose một POST request “/add” với data trong phần body là đối tượng document Question:
1 2 3 |
@PostMapping("/add") public Mono<Question> createQuestion(@RequestBody Question question) { } |
Bởi vì Spring MongoDB Reactive đã hỗ trợ cho chúng ta phương thức save() để lưu data vào MongoDB nên mình chỉ cần gọi để sử dụng phương thức này mà thôi:
1 2 3 4 |
@PostMapping("/add") public Mono<Question> createQuestion(@RequestBody Question question) { return questionRepository.save(question); } |
Đến đây thì chúng ta đã hoàn thành việc xây dựng API thêm mới question cho Core Question Service, hãy test thử xem sao nhé các bạn.
Phần cuối cùng mà chúng ta cần làm là thêm mới Unit Test cho code mà chúng ta vừa thêm vào.
Mình sẽ tạo mới một class tên là QuestionControllerTest nằm trong package src/test/java để test cho class QuestionController.
Mock class QuestionRepository:
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 đối tượng mock của QuestionRepository vào class QuestionController:
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; } |
Để sử dụng các đối tượng mock, chúng ta phải khởi tạo chúng trước mỗi lần test một phương thức nên mình sẽ thêm một phương thức với annotation @Before của JUnit như sau:
1 2 3 4 |
@Before public void init() { MockitoAnnotations.initMocks(this); } |
Code để test phương thức createQuestion() như sau:
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()); } |
Chạy “Maven test” trong STS hoặc “mvn test” với Apache Maven, các bạn sẽ không lỗi nào cả.