当我运行仿真测试时发生

错误细节:

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);

正如您所看到的,我在 updateItemAttributes上调用 when(它返回一个 boolean) ,而不是在 updateItemAttributesByJuId上。

  1. 为什么 Mockito 试图从 updateItemAttributesByJuId返回一个 boolean
  2. 这怎么能纠正呢?
196585 次浏览

根据 https://groups.google.com/forum/?fromgroups#!topic/mockito/9WUvkhZUy90,你应该重新措辞你的

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

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

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

我还遇到了一个多线程测试中的错误。

如果使用注释,可能需要使用@Mock 而不是@InjectMocks。因为@InjectMocks 扮演的是“间谍”和“嘲笑”的角色。而@Spy 会跟踪最近执行的方法,您可能会觉得返回/子选项是不正确的。

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

在我的例子中,问题是由于试图模仿一个静态方法并忘记在类上调用 mockStatic引起的。我还忘了把这个类加入到 @PrepareForTest()

我之所以出现这个错误,是因为在我的测试中,我有两个期望,一个是对模拟的期望,一个是对具体类型的期望

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();

我把类改成了模拟类,修正了这个问题

错误:

误用。错误类型返回值:
字符串不能由 size ()返回
Size ()应该返回 int
***
如果你不确定为什么你会得到以上错误继续读下去。
由于语法的性质,上述问题可能会发生,因为:
1. 此异常 也许吧出现在错误编写的多线程中
测试。
请参考 Mockito 关于并发测试限制的 FAQ。
2. 间谍使用 when (spy.foo ()) . then ()语法进行撞击
存根间谍-
- 使用 doReturn | Throw ()系列方法
间谍()方法。

实际代码:

@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);

对我来说,这意味着我正在运行这个:

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

所以发生了什么事情是,模仿者检测到 a.method2()被调用,并告诉我,我不能从 a.method2()返回 c,这是错误的。

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

或者在这个特定的例子中,在这样做之后,它开始显示更准确的“ NotAMockException”,我将其更改为不再尝试设置来自非模拟对象的返回值。

非常感兴趣的问题。 在我的例子中,这个问题是由于我试图在类似的行上调试我的测试而引起的:

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

重要的注意事项是,测试在没有调试的情况下正确运行。

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

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

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

我确保使用 org.mockito:mockito-inline来避免期末课程的问题(Arvidaa 提到过) ,但问题依然存在。解决这个问题的是 终止该进程并重新启动 Android Studio。这终止了我的冻结测试运行,下面的测试运行没有问题地通过了。

这是我的案子:

//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()是一个静态方法。

您想要模仿的 bean 上缺少@MockBean

在我的案例中,我同时使用 @RunWith(MockitoJUnitRunner.class)MockitoAnnotations.initMocks(this)。当我删除 MockitoAnnotations.initMocks(this)时,它正常工作。

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

Mockito 只是告诉我“ method something ()应该返回可选的”..。

在我的例子中,bean 是使用 @ Autowired注释而不是 @ MockBean初始化的

因此,通过这种方式嘲笑 DAO 和服务会抛出这样的异常

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

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

解决方案是为每个测试创建本地的模拟。

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


我在从 Spring 启动1.5. x 升级到2.1. x 时遇到了这个错误。Spring 启动附带了自己的 Mockito,现在也升级到了2.x (参见 Spring 启动2.1.2的依赖项)

Mockito 改变了 anyXXX()方法的行为,其中 XXXStringLong等等。以下是 anyLong()的 javadoc:

从 Mockito 2.1.0开始,只允许值 Long,因此 null不再是作为基元包装器的有效值 是可空的,则建议使用 火柴的 API null包装将是 #isNull()。我们感觉到了这种变化 会使测试工具比使用 Mockito 更安全 1.x.

我建议您调试到调用 mock 并检查 至少一个参数是否为 null的位置。在这种情况下,请确保您使用 isNull()而不是例如 anyLong()来准备您的模拟。

所以这个:

when(MockedClass.method(anyString());

变成:

when(MockedClass.method(isNull());

我正在使用 Scala,我得到了这样一条消息: 我错误地在两个 Object之间共享了一个 Mock。因此,请确保您的测试是相互独立的。并行测试执行显然会造成一些不稳定的情况,因为 Scala 中的对象是单例组合的。

仿生人

在我的例子中,或者更确切地说 Android项目的仪器测试中:

  • 有一次,我只需要删除 build目录(强制重新构建)。
  • 还有一次,计算机内存不足,导致所有打开的应用程序出现问题,重新启动每个应用程序就足够了(不需要重新启动计算机)。

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

但我希望这能帮到别人
D = (something something)

如今,由于命令行比 IDE 做得更好, 稍后在 IDE 中加载命令行创建的 test-result.pb文件 (所有测试结束后)。

在我的案例中,原来模拟对象的类型实际上是一个抽象接口,这个问题在将类型更改为某个实现类之后得到了解决,

改变

@Mock
private Proxy proxy;

@Mock
private ProxyImpl proxy;

我也遇到了同样的问题! 我创建了一个间谍在我的功能,并按照下面这样撞击它:

创造间谍

fktSpy: Class = Mockito.spy(class)

刺痛

Mockito.doReturn(value).`when`(fktSpy).function()

代码是在 Kotlin 写的