【问题标题】:Mocking Object that returns Java 8 Optional Object with Mockito returns Empty Optional使用 Mockito 返回 Java 8 Optional Object 的 Mocking Object 返回 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 并不陌生,所以我认为我在代码中没有任何问题,尽管由于长时间查看它,我可能在代码的某个地方犯了一个粗心的错误。有什么调试建议吗?

标签: java java-8 mocking mockito optional


【解决方案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 对象!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-05
    • 2019-11-03
    • 2017-02-20
    • 2021-06-10
    • 2022-01-06
    • 1970-01-01
    相关资源
    最近更新 更多