英文:
Unit testing void controller and service methods
问题
Controller方法:
@RequestMapping(method = RequestMethod.POST, value = "/products")
public void addProduct(@RequestBody Product product) {
productService.addProduct(product);
}
Service方法:
public void addProduct(Product product) {
productRepository.save(product);
}
Controller测试:
@Test
public void addProduct() {
Product product = new Product();
product.setId("001");
product.setName("TV");
product.setPrice(999.99);
doNothing().when(productService).addProduct(product); // 这里是模拟调用 productService.addProduct() 方法
productController.addProduct(product);
// 在这里可以添加断言来验证期望的行为是否发生
}
Service测试:
@Test
public void addProduct() {
Product product = new Product();
product.setId("001");
product.setName("TV");
product.setPrice(999.99);
when(productRepository.save(product)).thenReturn(product); // 这里是模拟调用 productRepository.save() 方法
Product savedProduct = productService.addProduct(product);
// 在这里可以添加断言来验证期望的行为是否发生
}
希望这些代码对你有所帮助。如果还有其他问题,请随时提问。
英文:
I have built a REST API that does basic CRUD operations on a product database and I am now unit testing all the methods within the controller and service layer. I have realised that methods such as addProduct, updateProduct or deleteProduct return void on both of the layers.
How do I go about mocking the repository when testing the service layer and mocking the service while testing controller layer for these methods?
Controller method:
@RequestMapping(method= RequestMethod.POST,value ="/products")
public void addProduct(@RequestBody Product product){
productService.addProduct(product);
}
Service method:
public void addProduct(Product product){
productRepository.save(product);
}
I have commented in the fields where I need help for the addProduct() methods.
Controller tests:
package com.product.controllers;
import com.product.entities.Product;
import com.product.services.ProductService;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class ProductControllerTest {
@InjectMocks
ProductController productController;
@Mock
ProductService productService;
@Test
public void getHomePage(){
String homePageText = "Welcome to the home page!";
assertEquals(homePageText,productController.getHomePage());
}
@Test
public void getAllProducts(){
Product product1 = new Product();
product1.setId("001");
product1.setName("TV");
product1.setPrice(999.99);
Product product2 = new Product();
product2.setId("002");
product2.setName("Mobile");
product2.setPrice(300D);
List<Product> listOfProducts = new ArrayList<>();
listOfProducts.add(product1);
listOfProducts.add(product2);
when(productService.getAllProducts()).thenReturn(listOfProducts);
assertEquals(listOfProducts,productController.getAllProducts());
}
@Test
public void getProductById(){
Product product = new Product();
product.setId("001");
product.setName("TV");
product.setPrice(999.99);
when(productService.getProductById("001")).thenReturn(product);
assertEquals(new ResponseEntity<Product> (product, HttpStatus.OK),productController.getProductById("001"));
}
@Test
public void addProduct() {
Product product = new Product();
product.setId("001");
product.setName("TV");
product.setPrice(999.99);
// need help with this
}
}
Service tests:
package com.product.services;
import com.product.entities.Product;
import com.product.repositories.ProductRepository;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
public class ProductServiceTest {
@InjectMocks
ProductService productService;
@Mock
ProductRepository productRepository;
@Test
public void getAllProducts() {
Product product1 = new Product();
product1.setId("001");
product1.setName("TV");
product1.setPrice(999.99);
Product product2 = new Product();
product2.setId("002");
product2.setName("Mobile");
product2.setPrice(300D);
List<Product> listOfProducts = new ArrayList<>();
listOfProducts.add(product1);
listOfProducts.add(product2);
when(productRepository.findAll()).thenReturn(listOfProducts);
assertEquals(listOfProducts, productService.getAllProducts());
}
@Test
public void getProductById() {
Product product = new Product();
product.setId("001");
product.setName("TV");
product.setPrice(999.99);
when(productRepository.findById("001")).thenReturn(java.util.Optional.of(product));
assertEquals(product, productService.getProductById("001"));
}
@Test
public void addProduct() {
Product product = new Product();
product.setId("001");
product.setName("TV");
product.setPrice(999.99);
// need help with this
}
}
答案1
得分: 1
这段代码非常简单,所以我不确定你是否需要对其进行单元测试。但如果你想要的话,你可以利用Mockito的模拟对象的verify
方法。例如,在测试addProduct
时:
@InjectMocks
ProductService productService;
@Mock
ProductRepository productRepository;
// ...
@Test
public void testAddProduct() {
Product dummyProduct = new Product();
productService.addProduct(dummyProduct);
// eq()来自于Mockito的匹配器包
Mockito.verify(productRepository, Mockito.times(1)).save(eq(dummyProduct))
}
这段代码验证了在模拟的仓库上是否正确调用了一次save
方法,并且传入的参数是dummyProduct
。
你可能还想了解一下Mockito的“参数捕获器”功能。
英文:
This code is quite simple so I'm not sure you need to unit test it. But if you want to, you can make use of your Mockito's mocks' verify
method. For example when testing addProduct
:
@InjectMocks
ProductService productService;
@Mock
ProductRepository productRepository;
// ...
@Test
public void testAddProduct() {
Product dummyProduct = new Product();
productService.addProduct(dummyProduct);
// eq() is from the Mockito matchers package
Mockito.verify(productRepository, Mockito.times(1)).save(eq(dummyProduct))
}
This verifies that save
was called on time on the mocked repository with an argument of dummyProduct
.
You also may want to check out Mockito "argument captors".
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论