当我运行mockito测试时发生WrongTypeOfReturnValue Exception

时间:2012-06-20 14:26:33

标签: java mockito

错误明细:

org.mockito.exceptions.misusing.WrongTypeOfReturnValue: 
Boolean cannot be returned by updateItemAttributesByJuId()
updateItemAttributesByJuId() should return ResultRich
This exception might occur in wrongly written multi-threaded tests.
Please refer to Mockito FAQ on limitations of concurrency testing.

我的代码:

@InjectMocks
protected ItemArrangeManager arrangeManagerSpy = spy(new ItemArrangeManagerImpl());
@Mock
protected JuItemWriteService juItemWriteService;

when(arrangeManagerSpy
    .updateItemAttributes(mapCaptor.capture(), eq(juId), eq(itemTO.getSellerId())))
    .thenReturn(false);

正如您所看到的,我在when上呼叫updateItemAttributes({1}},而boolean不在updateItemAttributesByJuId

  1. 为什么Mockito试图从boolean返回updateItemAttributesByJuId
  2. 如何纠正?

19 个答案:

答案 0 :(得分:145)

根据https://groups.google.com/forum/?fromgroups#!topic/mockito/9WUvkhZUy90,你应该改写你的

when(bar.getFoo()).thenReturn(fooBar)

doReturn(fooBar).when(bar).getFoo()

答案 1 :(得分:32)

类似错误消息的另一个原因是尝试模拟final方法。不应该试图模拟最终方法(参见Final method mocking)。

我还遇到了多线程测试中的错误。在这种情况下,gna的回答就是这样。

答案 2 :(得分:5)

非常感兴趣的问题。 在我的情况下,当我尝试在类似的行上调试我的测试时,会导致此问题:

Boolean fooBar;
when(bar.getFoo()).thenReturn(fooBar);

重要的是,测试运行正常,无需调试。

无论如何,当我用下面的代码片段替换上面的代码时,我能够毫无问题地调试问题行。

doReturn(fooBar).when(bar).getFoo();

答案 3 :(得分:4)

我最近遇到过这个问题。问题是我试图模拟的方法没有访问修饰符。添加公众解决了这个问题。

答案 4 :(得分:3)

在我的情况下,问题是由于尝试模拟静态方法而忘记在类上调用Option Explicit Public Verb1 As String Sub Paste2() Dim ws1 As Worksheet Dim ws2 As Worksheet Dim aCell As Range Dim Rng As Range Dim NextCol As Long Dim sFirstAddress As String Set ws1 = ThisWorkbook.Sheets("RawData") Set ws2 = ThisWorkbook.Sheets("Verbatim") Set Rng = ThisWorkbook.Sheets("RawData").Range("A1:ZZ1") NextCol = 0 'No need to "Activate" 'Worksheets("RawData").Activate With Rng 'Copy and Paste Verbatim Set aCell = .Find(what:=Verb1, after:=Rng.End(xlToRight), LookIn:=xlValues, _ lookat:=xlPart, searchorder:=xlByColumns, searchdirection:=xlNext, _ MatchCase:=False) If Not aCell Is Nothing Then sFirstAddress = aCell.Address NextCol = NextCol + 1 aCell.EntireColumn.Copy ws2.Cells(1, NextCol) Do Set aCell = .FindNext(aCell) If Not aCell.Address = sFirstAddress Then NextCol = NextCol + 1 aCell.EntireColumn.Copy ws2.Cells(1, NextCol) End If Loop Until sFirstAddress = aCell.Address End If End With End Sub 引起的。此外,我忘了将课程纳入mockStatic

答案 5 :(得分:3)

我遇到了这个错误,因为在我的测试中我有两个期望,一个是模拟,一个是具体类型

MyClass cls = new MyClass();
MyClass cls2 = Mockito.mock(Myclass.class);
when(foo.bar(cls)).thenReturn(); // cls is not actually a mock
when(foo.baz(cls2)).thenReturn();

我通过将cls更改为模拟来修复它

答案 6 :(得分:1)

就我而言,或者更确切地说是 Android 项目的仪器测试,
我只需要删除 build 目录(以强制重建)。

也许一个错误的原因太多了!
(他们应该已经解决了这个问题)。

但我希望这对某人有帮助
d= (◕‿↼ )

答案 7 :(得分:1)

TL; DR 如果测试中的某些参数是null,请确保使用isNull()而非anyXXX()模拟参数调用。


从Spring Boot 1.5.x升级到2.1.x时出现此错误。 Spring Boot附带了自己的Mockito,该Mockito现在也已升级到2.x(例如,Dependencies of Spring boot 2.1.2

Mockito更改了anyXXX()方法的行为,其中XXXStringLong等。这是anyLong()的Javadoc:< / p>

自Mockito 2.1.0起,仅允许值Long,因此 null不再是有效值,因为原始包装器 可以为空,建议匹配的API null包装器将为#isNull()。我们感受到了这种变化 可以使测试利用起来比Mockito更安全 1.x。

我建议您调试到将要调用您的模拟并检查至少一个自变量是否为null。在这种情况下,请确保您使用isNull()而不是例如{ anyLong()

所以这个:

when(MockedClass.method(anyString());

成为:

when(MockedClass.method(isNull());

答案 8 :(得分:1)

对我来说,问题是多线程测试正在对共享模拟进行存根/验证。它导致随机抛出WrongTypeOfReturnValue异常。

这不是使用Mockito正确编写的测试。 不应从多个线程访问模拟。

解决方案是使模拟在每个测试中都是本地的。

答案 9 :(得分:1)

对我而言,这意味着我正在运行这个:

a = Mockito.mock(SomeClass.class);
b = new RealClass();
when(b.method1(a)).thenReturn(c); 
// within this method1, it calls param1.method2() -- note, b is not a spy or mock

所以发生的事情是,mockito正在检测到a.method2()被调用,并且告诉我,我无法从c返回a.method2()这是错误的。

修复:使用doReturn(c).when(b).method1(a)样式语法(而不是when(b.method1(a)).thenReturn(c);),这将帮助您更简洁快速地发现隐藏的错误。

或者在这种特殊情况下,在执行此操作后,它开始显示更准确的&#34; NotAMockException&#34;,并且我将其更改为不再尝试从非模拟对象设置返回值。

答案 10 :(得分:1)

如果您正在使用注释,可能需要使用@Mock而不是@InjectMocks。因为@InjectMocks在@Spy和@Mock一起工作。 @Spy会跟踪最近执行的方法,您可能会觉得返回/提交了不正确的数据。

答案 11 :(得分:0)

我最近在模拟 Kotlin数据类中的函数时遇到了此问题。由于某种未知的原因,我的测试运行最终陷入了冻结状态。当我再次运行测试时,以前通过的某些测试因WrongTypeOfReturnValue异常而开始失败。

我确保使用org.mockito:mockito-inline来避免最终类的问题(由Arvidaa提及),但是问题仍然存在。为我解决的是终止该过程并重新启动Android Studio 。这终止了我的冻结测试运行,随后的测试运行顺利通过。

答案 12 :(得分:0)

这是我的情况:

//given
ObjectA a = new ObjectA();
ObjectB b = mock(ObjectB.class);
when(b.call()).thenReturn(a);

Target target = spy(new Target());
doReturn(b).when(target).method1();

//when
String result = target.method2();

然后我得到这个错误:

org.mockito.exceptions.misusing.WrongTypeOfReturnValue: 
ObjectB$$EnhancerByMockitoWithCGLIB$$2eaf7d1d cannot be returned by method2()
method2() should return String

你能猜到吗?

问题在于Target.method1()是静态方法。 Mockito完全警告我另一件事。

答案 13 :(得分:0)

要模拟的bean缺少@MockBean

答案 14 :(得分:0)

就我而言,我同时使用了@RunWith(MockitoJUnitRunner.class)MockitoAnnotations.initMocks(this)。当我删除MockitoAnnotations.initMocks(this)时,它可以正常工作。

答案 15 :(得分:0)

我遇到了这个问题WrongTypeOfReturnValue,因为我的格式化程序自动添加了缺少的导入内容,因此我模拟了一个返回java.util.Optional;com.google.common.base.Optional;的方法。

Mockito只是在说我“ method something()应该返回Optional” ...

答案 16 :(得分:0)

在我的情况下,已使用 @Autowired 注释而不是 @MockBean

初始化了bean。

因此,通过这种方式对DAO和服务进行模拟会抛出此类异常

答案 17 :(得分:0)

错误:

  

org.mockito.exceptions.misusing.WrongTypeOfReturnValue:
  size()
不能返回字符串   size()应返回int
  ***
  如果你不确定为什么你上面读错了。
  由于上述语法的性质,可能会出现问题,因为:
  1.此异常可能发生在错误编写的多线程中   试验。
  有关并发性测试的限制,请参阅Mockito常见问题解答   2.使用when(spy.foo())。then()语法时,间谍是存根的。更安全   存根间谍 -
   - 使用doReturn | Throw()系列方法。更多关于
的javadocs   Mockito.spy()方法。

实际代码:

@RunWith(PowerMockRunner.class)
@PrepareForTest({ Object.class, ByteString.class})

@Mock
private ByteString mockByteString;

String testData = “dsfgdshf”;
PowerMockito.when(mockByteString.toStringUtf8()).thenReturn(testData); 
// throws above given exception

解决此问题的解决方法:

首先删除注释“@Mock”。

private ByteString mockByteString;

第二次添加PowerMockito.mock

mockByteString = PowerMockito.mock(ByteString.class);

答案 18 :(得分:0)

我正在使用 Scala 并且收到此消息,其中我错误地在两个 Object 之间共享了一个 Mock。因此,请确保您的测试彼此独立。并行测试执行显然会产生一些不稳定的情况,因为 Scala 中的对象是单例组合。