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.
Trong bài viết trước, chúng ta đã chuẩn bị tất cả các cấu hình cần thiết để có thể xây dựng API tìm question theo id có trong MongoDB database như: một đối tượng document Question chứa thông tin của một question, một QuestionRepository để thao tác với MongoDB, một QuestionController định nghĩa các API của Core Question Service sẽ bắt đầu với “/question” và thông tin về kết nối đến MongoDB server được cấu hình trong tập tin application.properties. Bây giờ, chúng ta sẽ tiến hành xây dựng API để này các bạn nhé!
Để xây dựng API tìm question theo id, mình sẽ thêm mới một method để expose một GET request “/{id}” với id là id của question mà chúng ta cần tìm:
1 2 3 4 |
@GetMapping("/{id}") public Mono<ResponseEntity<Question>> findQuestionById(@PathVariable(value = "id") String questionId) { } |
Các bước để tìm question theo id bao gồm:
Đầu tiên, chúng ta cũng cần phải kiểm tra xem là question mà chúng ta cần tìm có tồn tại hay không dựa vào id mà người dùng truyền vào.
Spring Data MongoDB Reactive đã hỗ trợ cho chúng ta phương thức để tìm kiếm theo id nên chúng ta chỉ cần gọi để sử dụng mà thôi.
1 |
questionRepository.findById(questionId) |
Trong trường hợp question này tồn tại, chúng ta sẽ return nó sử dụng phương thức map() với HTTP status code là 200:
1 2 |
questionRepository.findById(questionId) .map(question -> ResponseEntity.ok(question)) |
Trong trường hợp question này không tồn tại trong database thì chúng ta sẽ trả về kết quả HTTP status code là 404 Not Found.
1 2 3 |
questionRepository.findById(questionId) .map(question -> ResponseEntity.ok(question)) .defaultIfEmpty(ResponseEntity.notFound().build()); |
Toàn bộ nội dung của phương thức findQuestionById() sẽ như sau:
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()); } |
Đến đây thì chúng ta đã hoàn thành việc xây dựng API để tìm question theo id cho Core Question Service, hãy test thử xem sao nhé các bạn.
Giả sử hiện tại trong database mình đang có những question như sau:
thì khi mình request để tìm question với id là 5ad5d9d651bd7a0aefa87fb3, kết quả sẽ là:
Bây giờ chúng ta sẽ thêm mới Unit Test cho code mà chúng ta vừa thêm vào, các bạn nhé!
Trong bài viết trước, mình đã tạo mới class test cho QuestionController tên là QuestionControllerTest, đối tượng Mock cho QuestionRepository và inject đối tượng Mock này vào class QuestionController, khởi tạo các đối tượng Mock mỗi khi chạy một test case 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 |
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); } } |
Giờ mình sẽ thêm mới hai phương thức để test cho phương thức của findQuestionById() của class QuestionController như sau:
Một phương thức để test cho trường hợp có question dựa vào id truyền vào:
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()); } |
Một phương thức để test cho trường hợp không có question với id truyền vào:
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()); } |
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ả.