【问题标题】:org.mockito.exceptions.misusing.WrongTypeOfReturnValue:org.mockito.exceptions.misusing.WrongTypeOfReturnValue:
【发布时间】:2020-01-07 23:25:12
【问题描述】:

我正在尝试执行简单的单元测试,但它仍然会抛出 null 或一些奇怪的错误,例如:

org.mockito.exceptions.misusing.WrongTypeOfReturnValue: 
Ticket cannot be returned by findById()
findById() should return Optional

这是为什么呢?相反,代码将无法编译。

测试看起来像这样:

@Test
void updateTicketByOrderAmount() {

    OrderedTicket orderedTicket = OrderedTicketDatasource.getOrderedTicket();

    Ticket ticket = TicketDatasource.getTicket();

    when(ticketRepository.findById(ticket.getId())).thenReturn(Optional.of(ticket));

    when(ticketService.findById(ticket.getId())).thenReturn(ticket);

    Ticket actual = ticketService.updateTicketByOrderAmount(orderedTicket);

    assertNotNull(actual);

}

和实施:

@Override
    @Transactional
    public Ticket updateTicketByOrderAmount(OrderedTicket orderedTicket) {
        Ticket found = findById(orderedTicket.getTicket().getId());

        decreaseInStockAmount(orderedTicket, found);

        return ticketMapper.ticketDTOtoTicket(
                saveOrUpdateTicket(
                        ticketMapper.ticketToTicketDTO(found)
                )
        );
    }

 @Override
    public Ticket findById(Long id) {
        return ticketRepository.findById(id).orElseThrow(ResourceNotFoundException::new);
    }


 private void decreaseInStockAmount(OrderedTicket ticket, Ticket found) {
        found.setInStock(
                found.getInStock() - ticket.getAmount()
        );
    }

完整的堆栈跟踪:

org.mockito.exceptions.misusing.WrongTypeOfReturnValue: 
Ticket cannot be returned by findById()
findById() should return Optional
***
If you're unsure why you're getting above error read on.
Due to the nature of the syntax above problem might occur because:
1. This exception *might* occur in wrongly written multi-threaded tests.
   Please refer to Mockito FAQ on limitations of concurrency testing.
2. A spy is stubbed using when(spy.foo()).then() syntax. It is safer to stub spies - 
   - with doReturn|Throw() family of methods. More in javadocs for Mockito.spy() method.


    at server.eventooserver.api.v1.service.TicketServiceImplTest.updateTicketByOrderAmount(TicketServiceImplTest.java:90)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:532)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:115)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:170)
    at org.junit.jupiter.engine.execution.ThrowableCollector.execute(ThrowableCollector.java:40)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:166)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:113)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:58)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$4(NodeTestTask.java:108)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:98)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:74)
    at java.util.ArrayList.forEach(ArrayList.java:1257)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$4(NodeTestTask.java:112)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:98)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:74)
    at java.util.ArrayList.forEach(ArrayList.java:1257)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$4(NodeTestTask.java:112)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:98)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:74)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:220)
    at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:188)
    at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:202)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:181)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
    at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:74)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

它直接指向

when(ticketService.findById(ticket.getId())).thenReturn(ticket);

但这是为什么呢?

我还要附上 mock 是如何初始化的:

   @Mock
    TicketRepository ticketRepository;

    TicketService ticketService;

    public TicketServiceImplTest() {
        MockitoAnnotations.initMocks(this);
        ticketService = new TicketServiceImpl(ticketRepository);
    }

我知道ticketService 不是Mock,但如果我删除这条线,它会抛出:

org.opentest4j.AssertionFailedError: expected: not <null>

    at org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:38)
    at org.junit.jupiter.api.Assertions.fail(Assertions.java:84)
    at org.junit.jupiter.api.AssertNotNull.failNull(AssertNotNull.java:47)
    at org.junit.jupiter.api.AssertNotNull.assertNotNull(AssertNotNull.java:36)
    at org.junit.jupiter.api.AssertNotNull.assertNotNull(AssertNotNull.java:31)
    at org.junit.jupiter.api.Assertions.assertNotNull(Assertions.java:258)
    at server.eventooserver.api.v1.service.TicketServiceImplTest.updateTicketByOrderAmount(TicketServiceImplTest.java:94)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:532)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:115)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:170)
    at org.junit.jupiter.engine.execution.ThrowableCollector.execute(ThrowableCollector.java:40)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:166)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:113)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:58)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$4(NodeTestTask.java:108)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:98)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:74)
    at java.util.ArrayList.forEach(ArrayList.java:1257)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$4(NodeTestTask.java:112)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:98)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:74)
    at java.util.ArrayList.forEach(ArrayList.java:1257)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$4(NodeTestTask.java:112)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:98)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:74)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:220)
    at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:188)
    at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:202)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:181)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
    at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:74)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

以及来自调试器的屏幕截图

【问题讨论】:

  • 那么哪一个返回Optional&lt;Ticket&gt;TicketService.findByIdTicketRepository.findById
  • TicketRepository 返回 Ticket 的 Optional,其中 TicketService 只返回 Ticket
  • “我知道ticketService 不是Mock,但如果我删除这条线,它会抛出......”。是的,但是您必须删除该行。因为它不是模拟,但您正试图模拟对它的方法调用。您的根本问题是最后一个堆栈跟踪,即为什么返回 null
  • 我知道,但是使用此存储库方法的其他方法通过了。
  • 您是否已经删除了when(ticketService.findById(ticket.getId())).thenReturn(ticket); 行?如果你不删除它,你将无处可去。

标签: java spring-boot unit-testing junit


【解决方案1】:

要进行的更改:

  1. thenReturn(Optional.of(ticket));

thenReturn 里面的参数因为Optional.of() 不能是null。而是使用Optional.ofNullable(T value)。返回一个描述指定值的Optional,如果非null,否则返回一个空。

  1. when(ticketService.findById(ticket.getId())).thenReturn(ticket); 更改为doReturn(ticket).when(ticketService).findById(ticket.getId())

阅读: https://groups.google.com/forum/?fromgroups#!topic/mockito/9WUvkhZUy90

【讨论】:

  • 不是根本原因,因为这涉及到间谍并调用真正的方法。
  • 谢谢,但现在它被抛出:org.mockito.exceptions.misusing.NotAMockException:传递给 when() 的参数不是模拟!正确存根示例:doThrow(new RuntimeException()).when(mock).someMethod();
猜你喜欢
  • 1970-01-01
  • 2023-04-05
  • 1970-01-01
相关资源
最近更新 更多