如何在 Spring Boot REST API 中为 db insert 方法编写模拟单元测试?

Posted

技术标签:

【中文标题】如何在 Spring Boot REST API 中为 db insert 方法编写模拟单元测试?【英文标题】:How to write a mocked unit test for a db insert method in Springboot REST API? 【发布时间】:2021-05-18 18:51:06 【问题描述】:

我有一个用 Spring Boot 编写的 REST API。

现在我想用 JUnit 和 Mockito 创建单元测试来模拟数据库操作。

这是将新客户插入数据库的端点。

@RestController
public class CustomerController 
    
    @Autowired
    private CustomerRepository customerRepository;
    
    
    @PostMapping(value="/customers", produces = "application/json")
    public ResponseEntity<Customer> addCustomer(@RequestBody Customer customer)
        
        Customer newCustomer = customerRepository.save(customer);       
        
        return new ResponseEntity<Customer>(newCustomer, HttpStatus.OK) ;
    

测试:

@Test
public void testAddCustomer() 
        
    Customer customer = Mockito.mock(Customer.class);
    customer.setIdCustomer(1L);     
    customer.setName("Pete");
    customer.setAge(35);
    customer.setEmail("pete@test.com");
                
    when(customerRepository.save(customer)).thenReturn((Customer) Stream.of(customer));
        
    CustomerController customerController = new CustomerController();       

    ResponseEntity<Customer> respCustomer = customerController.addCustomer(customer);
        
    assertTrue(respCustomer.getBody().getIdCustomer() != null);
        

我在以下行收到空指针异常:

 when(customerRepository.save(customer)).thenReturn((Customer) Stream.of(customer));

【问题讨论】:

【参考方案1】:

使用

@Mock private CustomerRepository customerRepository

在您的测试中使用 mockito API 配置存储库

【讨论】:

@Test 方法的代码是什么?这就是我想要弄清楚的。 我更新了问题,添加了我目前所拥有的内容。【参考方案2】:

应该是这样的

    @Test
    public void testFindTheGreatestFromAllData() 
        DataService dataServiceMock = mock(DataService.class);
        when(dataServiceMock.retrieveAllData()).thenReturn(new int[]  24, 15, 3 );
        SomeBusinessImpl businessImpl = new SomeBusinessImpl(dataServiceMock);
        int result = businessImpl.findTheGreatestFromAllData();
        assertEquals(24, result);
    

【讨论】:

我更新了问题,添加了到目前为止我所拥有的不起作用的内容。 在运行测试时检查 customRepository 是否不为空。使用断点和调试模式 是的,它是空的。如何解决?它在类级别自动装配。 public class CustomerControllerTest @Autowired private CustomerRepository customerRepository;... 现在我注意到我在嘲笑错误的课程。存储库类是需要模拟的类。所以我做了以下更改:1)注释掉@Autowired行; 2) 将 testAddCustomer 方法的第一行更改为 Customer customer = new Customer(); 3) 添加以下行:CustomerRepository customerRepository = Mockito.mock(CustomerRepository.class);现在出现类型转换错误:java.lang.ClassCastException: class java.util.stream.ReferencePipeline$Head 无法转换为 class restapicustomers.model.Customer

以上是关于如何在 Spring Boot REST API 中为 db insert 方法编写模拟单元测试?的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot JWT - 如何实现刷新令牌和注销 REST-API

如何在 Spring Boot REST API 中格式化返回的 json?

在 Spring-boot 中成功登录后如何限制 POST Rest Api 以供公共访问

如何在 Spring Boot Rest api 响应的 ResponseEntity 中添加自定义属性

如何在 Spring Boot Rest API 中以 XML 形式返回对象列表

如何在 Spring Boot Rest api 中创建安全登录控制器