首页 > 解决方案 > 为什么@Spy Abc abc 无法获取已经存在的实例?

问题描述

我有 junit 测试用例,其中我以以下方式使用了 Spy,而 Junit 在以下情况下失败。

@Spy
private Abc abc;

但为此成功运行。

@Spy  Abc abc =  new Abc(); 

有人可以解释我为什么吗?此外,在此语句 @Spy Abc abc = new Abc(); 中是否创建了一个新实例,或者它是使用现有实例,即Autowired.

标签: javajunitmockito

解决方案


使用@Spy注释时,Mockito 会将现有实例包装在 spy 对象中。注释的@Spy工作方式类似于以下代码:

Abc spyAbc = Mockito.spy(new Abc());

这意味着,这两个表达式将产生相同的结果:

@Spy Abc abc = new Abc();
Abc abc = Mockito.spy(new Abc());

以下语句仅在存在默认构造函数时才有效:

@Spy Abc abc;

使用间谍,间谍对象的行为与您的原始实现相同(尽管您可以使用例如定义自定义测试行为

Mockito.doReturn(1).when(abc).myMethod();

相反,使用模拟对象 ( Mockito.mock(Abc.class)) 不会提供与原始实现相同的行为,因为它不是类的真实实例。

当你想窥探春豆时,你必须有可能的方法:

像这样使用@SpyBean(参见:https ://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/test/mock/mockito/SpyBean.html):

@SpyBean
private Abc abc;

或结合使用@Autowiredand@Spy

@Spy
@Autowired
private Abc abc;

两种方式都会奏效。请注意 和 的when(abc.method()).thenReturn(1);区别doReturn(1).when(abc).method();。只有在第一种情况下method()才被实际调用(并且只有它的返回被修改)。对于第二个示例,不会调用该方法。这种差异对于了解该方法是否有副作用很重要。


推荐阅读