使用 Mockito 返回 Java 8 Optional Object 的 Mocking Object 返回 Empty Optional

Posted

技术标签:

【中文标题】使用 Mockito 返回 Java 8 Optional Object 的 Mocking Object 返回 Empty Optional【英文标题】:Mocking Object that returns Java 8 Optional Object with Mockito returns Empty Optional 【发布时间】:2019-07-20 05:35:19 【问题描述】:

我正在尝试使用 Mockito 模拟一个返回 Java 可选对象的对象:

SomeObject someObject = new SomeObject();
Mockito.when(someSpringJpaRepository.findById(Mockito.any(UUID.class))).thenReturn(Optional.of(someObject));

someSpringJpaRepository.findById(UUID)被调用时,它返回Optional.empty

我期待方法 findById() 返回 someObject。 为什么它会返回Optional.empty

方法如下:

public UUID saveOrder(OrderDTO orderDto) 

        Order order = new Order();
        if (orderDto.getId() != null) 
            Optional<Order> result = orderRepository.findById(orderDto.getId());
            if (result != null && result.isPresent()) 
                order = result.get(); // existing record

             else 
                order.setId(UUID.randomUUID());
            
         else 
            // new record
            order.setId(UUID.randomUUID());
        

        return order.getId();
    

这里是 Junit:

@Test
    public void saveOrderTest()

        @Autowired
        private OrderApiService orderApiService;
        @Mock
        private OrderRepository orderRepository;

        OrderDTO orderDto = new OrderDTO();
        UUID orderID = UUID.randomUUID();
        Order order = new Order();
        order.setId(orderID);

        orderDto.setId(orderID);
        Mockito.when(orderRepository.findById(Mockito.any(UUID.class))).thenReturn(Optional.of(order));
        assertNotNull(orderApiService.saveOrder(orderDto));
    

【问题讨论】:

请在问题中分享findById 的签名。如果该方法的返回类型为Optional&lt;T&gt;,那么您的模拟是正确的,但期望不正确。如果该方法的返回类型为T,那么您的模拟不正确,您可能需要将其更改为.thenReturn(someObject) findById 是 Spring CrudRepository 方法。我没有在实现someSpringJpaRepository中重写这个方法的行为你可以在这里找到文档:docs.spring.io/spring-data/commons/docs/current/api/org/… findById() 返回Optional&lt;T&gt;。因此,您认为我的期望是不正确的。在这种情况下,我的期望是什么?谢谢! 如果该方法返回一个Optional&lt;T&gt;,那么期望在这种情况下它可以返回Optional&lt;SomeObject&gt;。虽然如果结果是Optional.empty,我仍然会怀疑。 是的,这绝对是粗略的!我对 Junit 和 Mockito 并不陌生,所以我认为我在代码中没有任何问题,尽管由于长时间查看它,我可能在代码的某个地方犯了一个粗心的错误。有什么调试建议吗? 【参考方案1】:

你在课堂上的@Mock 什么都不做。您创建了一个单独的 orderRepository 实例,它没有注入到您的服务类中。要将你的模拟注入到上下文中,请使用@MockBean

@Mock@MockBean here 之间的区别

【讨论】:

【参考方案2】:

你可以尝试使用spy方法

Repository spyRepo = Mockito.spy(someSpringJpaRepository);
Mockito.doReturn(Optional.of(someObject)).when(spyRepo).findById(Mockito.any(UUID.class));

【讨论】:

感谢您的建议!但是,从 mock 切换到 spy 产生了相同的结果,一个空的 Optional 对象!

以上是关于使用 Mockito 返回 Java 8 Optional Object 的 Mocking Object 返回 Empty Optional的主要内容,如果未能解决你的问题,请参考以下文章

Mockito 对象不是声明类的实例

Mockito单元测试保姆级实战(一个java Mock测试框架)

Mockito单元测试保姆级实战(一个java Mock测试框架)

mockito使用心得

mockito 异常Reason: java.io.IOException: invalid constant type: 18

Java mockito - 如何在循环中添加return语句?