I want to detail the steps that I try to take when creating a new endpoint in a backend project (Java, SpringBoot, Mockito). Definitely this is not the same all the time, but that's not the topic for this post.
The task is: implement a new endpoint that retrieves all the products that exist at the moment.
Steps:
- create a new method in the service class that retrieves using persistence layer (no queries allowed here) all the products available
- create endpoint that calls the above service method and returns data
- create unit test for service method
- create integration test for the new endpoint.
This is my way of testing, you can mix the points as you like.
We are decoupling the persistence (VendorProductRepository) and business(VendorProductService) layers.
public List<VendorProduct> findAllProducts() {
return getVendorProductsRepository().findAll();
}
This is the actual endpoint, which has one liner in this case. It simply returns the result of the service call.
@GetMapping("/")
public ResponseEntity<?> getAllProducts() {
return ResponseEntity.ok(vendorProductsService.findAllProducts());
}
This unit test describes the 'given' - 'when' - 'then'. We create a dummy object which we add to a list. The given part is when we describe(stub) what code will do when the repository is asked to return all products. The when part is when we call the service method, and the then part is when we verify the mocked service call returns the initially given list.
@Test
public void findAllProducts_always_returns_all_existing_products() {
List<VendorProduct> productList = new ArrayList<>();
productList.add(EntityHelper.convertToAbstractEntity(vendorProductDto, VendorProduct.class));
when(repository.findAll()).thenReturn(productList);
List<VendorProduct> foundProducts = subject.findAllProducts();
assertNotNull(foundProducts);
assertEquals(foundProducts.size(), productList.size());
}
This integration test, describes the happy path for retrieving a list of all available products. It hits the database so it's best to be made on a developer version of it. We make the Http call and check against the HttpStatus response and body.
@Test
public void testGetAllProducts_shouldReturn_list_of_existing_products() {
VendorProduct vendorProduct = new VendorProduct();
vendorProduct.setId(1L);
vendorProduct.setName("Mint Plants will be deleted");
vendorProduct.setMinQuantityPerOrder(3d);
vendorProduct.setMaxQuantityPerOrder(100d);
vendorProduct.setQuantityType(QuantityType.ITEM.getIndex());
List<VendorProduct> existingProducts = new ArrayList<>();
existingProducts.add(vendorProduct);
ResponseEntity<List> getResponse = getRestTemplate().getForEntity(getRootUrl() + "/products/", List.class);
assertEquals(HttpStatus.OK, getResponse.getStatusCode());
assertEquals(existingProducts, getResponse.getBody());
}
This is when I feel more confident that adding a new endpoint to do something will actually work. This code is actually part of my #twiliohackathon project, so the code is public here https://github.com/gabrielaradu/BuyLocalServerSide
Happy coding.
Top comments (0)