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 cập nhập một category như: một đối tượng Category để chứa thông tin của một category, một interface CoreCategoryService với implementation là CoreCategoryServiceImpl có trách nhiệm thao tác với Core Category Service, một CategoryController định nghĩa các API của API Category Service sẽ bắt đầu với “/category” và thông tin về Core Category Service đượ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 cập nhập category, đầu tiên, mình sẽ thêm mới một phương thức updateCategory() trong interface CoreCategoryService:
1 |
Mono<Category> updateCategory(String categoryId, Category category); |
với phần implementation của method này trong class CoreCategoryServiceImpl như sau:
1 2 3 4 5 6 7 8 9 10 11 12 |
@Override public Mono<Category> updateCategory(String categoryId, Category category) { WebClient webClient = WebClient.builder() .baseUrl(getServiceUrl()) .build(); return webClient.put() .uri("/category/" + categoryId) .body(BodyInserters.fromObject(category)) .retrieve() .bodyToMono(Category.class); } |
Như các bạn thấy, ở đây mình đã sử dụng đối tượng WebClient để kết nối tới Core Category Service và gọi API cập nhập category của service này với URI “/category/{id}”.
Tiếp theo, mình sẽ thêm mới một method gọi tới phương thức updateCategory() của CoreCategoryService để expose một PUT request “/category/{id}” trong CategoryController:
1 2 3 4 5 6 |
@PutMapping("/{id}") public Mono<ResponseEntity<Category>> updateCategory(@PathVariable(value = "id") String categoryId, @RequestBody Category category) { return coreCategoryService.updateCategory(categoryId, category) .map(c -> ResponseEntity.ok(c)) .defaultIfEmpty(ResponseEntity.notFound().build()); } |
Đến đây thì chúng ta đã hoàn thành việc xây dựng API cập nhập category cho API Category Service, hãy test thử xem sao nhé các bạn.
Giả sử hiện tại ứng dụng Questions Management của chúng ta đang có những category như sau:
Nếu giờ mình update category với id là “5b234312f2581f2c0c276a58” thì kết quả sẽ như sau:
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 CoreCategoryService và inject đối tượng Mock này vào class CategoryController, khởi tạo mock mỗi khi chạy một test case:
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.categoryservice; import org.junit.Before; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import com.huongdanjava.categoryservice.service.CoreCategoryService; public class CategoryControllerTest { @Mock private CoreCategoryService coreCategoryService; @InjectMocks private CategoryController categoryController; @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 |
@Test public void testUpdateExistingCategory() { // Category information need to be updated Category updateCategory = new Category(); updateCategory.setCode("ABC"); updateCategory.setName("ZXCV"); // Category object will be returned after updating Category category = new Category(); category.setId("123"); category.setCode("ABC"); category.setName("ZXCV"); // Mock updateCategory() method of CoreCategoryService to return above category when(coreCategoryService.updateCategory("123", updateCategory)).thenReturn(Mono.just(category)); // 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 |
@Test public void testUpdateNoExistingCategory() { // Category information need to be updated Category updateCategory = new Category(); updateCategory.setCode("ABC"); updateCategory.setName("ZXCV"); // Mock updateCategory() method of CoreCategoryService to return an empty Mono when(coreCategoryService.updateCategory("123", updateCategory)).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ả.
vi
anh ơi interface Mono<ResponseEntity> updateCategory(String categoryId, Category category); mà implement nó public Mono updateCategory như vậy là implement của nó thiếu ResponseEntity phải ko nhỉ
, cho em hỏi là ResponseEntity chức năng nó là gì nhỉ
Khanh Nguyen
Thanks em. Anh update lại rồi em nhé! Mình không cần sử dụng class ResponseEntity trong interface này.
ResponseEntity để mình có thể set các thông tin về header trong reponse đó em!