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.
Như mình đã đề cập, trong bài viết trước, chúng ta đã chuẩn bị tất cả các thông tin, cấu hình cần thiết để có thể xây dựng API cập nhập category như: một đối tượng document Category chứa thông tin của một category, một CategoryRepository để thao tác với MongoDB, một CategoryController định nghĩa các API của Core Category Service sẽ bắt đầu với “/category” 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 để cập nhập một category các bạn nhé!
Để xây dựng API cập nhập category, mình sẽ thêm mới một method để expose một PUT request “{id}” với id là id của category mà chúng ta cần cập nhập. Chúng ta cũng cần định nghĩa thêm phần body data là nội dung mới của category mà chúng ta sẽ cập nhập như sau:
1 2 3 4 5 6 |
@PutMapping("/{id}") public Mono<ResponseEntity<Category>> updateCategory( @PathVariable(value = "id") String categoryId, @RequestBody Category category) { } |
Các bước để cập nhập một category bao gồm:
Đầu tiên, chúng ta cũng cần phải kiểm tra là category mà chúng ta cần cập nhập 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 |
categoryRepository.findById(categoryId) |
Trong trường hợp category này tồn tại, chúng ta sẽ sử dụng các thông tin được truyền trong phần body data để cập nhập thông tin trong database:
1 2 3 4 5 6 7 8 |
categoryRepository.findById(categoryId) .flatMap(existingCategory -> { existingCategory.setCode(category.getCode()); existingCategory.setName(category.getName()); existingCategory.setDescription(category.getDescription()); return categoryRepository.save(existingCategory); }) |
Sau đó thì trả về cho người dùng thông tin mới của category này sau khi đã cập nhập vào database với HTTP status code là 200 OK.
1 2 3 4 5 6 7 8 9 |
categoryRepository.findById(categoryId) .flatMap(existingCategory -> { existingCategory.setCode(category.getCode()); existingCategory.setName(category.getName()); existingCategory.setDescription(category.getDescription()); return categoryRepository.save(existingCategory); }) .map(updatedCategory -> new ResponseEntity<>(updatedCategory, HttpStatus.OK)) |
Trong trường hợp category 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 4 5 6 7 8 9 10 |
categoryRepository.findById(categoryId) .flatMap(existingCategory -> { existingCategory.setCode(category.getCode()); existingCategory.setName(category.getName()); existingCategory.setDescription(category.getDescription()); return categoryRepository.save(existingCategory); }) .map(updatedCategory -> new ResponseEntity<>(updatedCategory, HttpStatus.OK)) .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND)); |
Toàn bộ nội dung của phương thức updateCategory() lúc này sẽ như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
@PutMapping("/{id}") public Mono<ResponseEntity<Category>> updateCategory( @PathVariable(value = "id") String categoryId, @RequestBody Category category) { return categoryRepository.findById(categoryId) .flatMap(existingCategory -> { existingCategory.setCode(category.getCode()); existingCategory.setName(category.getName()); existingCategory.setDescription(category.getDescription()); return categoryRepository.save(existingCategory); }) .map(updatedCategory -> new ResponseEntity<>(updatedCategory, HttpStatus.OK)) .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND)); } |
Đến đây thì chúng ta đã hoàn thành việc xây dựng API để cập nhập một category cho Core Category 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 category sau:
thì khi mình request để cập nhập category với id là 5b297751366e2605cf3c0d3e:
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 CategoryController tên là CategoryControllerTest, đối tượng Mock cho CategoryRepository và inject đối tượng Mock này vào class CategoryController:
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; } |
Khởi tạo mock mỗi khi chạy một test case:
1 2 3 4 |
@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 updateCategory() của class CategoryController như sau:
Một phương thức để test cho trường hợp có category 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 25 26 27 28 29 30 31 |
@Test public void testUpdateExistingCategory() { // Create category document to return when using findById Category category = new Category(); category.setId("123"); category.setCode("ABC"); category.setName("ZXC"); // Category information need to be updated Category updateCategory = new Category(); updateCategory.setId("123"); updateCategory.setCode("ABC"); updateCategory.setName("ZXCV"); // Mock findById() method of CategoryRepository to return above category when(categoryRepository.findById("123")).thenReturn(Mono.just(category)); // Mock save() method of CategoryRepository when(categoryRepository.save(category)).thenReturn(Mono.just(updateCategory)); // Call method Mono<ResponseEntity<Category>> update = categoryController.updateCategory("123", updateCategory); ResponseEntity<Category> responseEntity = update.block(); // Assertions assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); Category responseCategory = responseEntity.getBody(); assertEquals("ZXCV", responseCategory.getName()); } |
Một phương thức để test cho trường hợp không có category 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 |
@Test public void testUpdateNoExistingCategory() { // Category information need to be updated Category updateCategory = new Category(); updateCategory.setId("123"); updateCategory.setCode("ABC"); updateCategory.setName("ZXCV"); // Mock findById() method of CategoryRepository to return an empty Mono when(categoryRepository.findById("123")).thenReturn(Mono.empty()); // Call method Mono<ResponseEntity<Category>> update = categoryController.updateCategory("123", updateCategory); ResponseEntity<Category> 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ả.
meomun
anh ơi sửa lại phần này ạ:
thì khi mình request để xoá category với id là 5b297751366e2605cf3c0d3e:
hình như phần này là phần update ạ
Khanh Nguyen
Ôi, em giúp anh review lại hết tất cả nhé! Nhiều quá đôi lúc anh viết sai. Thank em đã nhắc anh. Anh đang tính sau khi hoàn thiện Giai đoạn 1 sẽ review lại và nhờ một số bạn review giúp. Hi vọng lúc đó em sẽ giúp anh nhé!
meomun
dạ, em đang làm lại project của anh, có gì em note lại ạ.