Spring (@SpyBean) 与 Mockito (@Spy)

12

@SpyBeanorg.springframework.boot.test.mock.mockito.SpyBean中的@Spy有什么区别?

在我的测试中,使用@SpyBean而不是@Spy导致测试失败。

2个回答

18

@Spy 文档 中说明:

使用@Spy注释的字段可以在声明点显式初始化。或者,如果您不提供实例,Mockito将尝试查找零参数构造函数(甚至是私有的)并为您创建一个实例。

@SpyBean 文档 中说明:

此注释可用于将Mockito间谍应用于Spring ApplicationContext。

上下文中所有相同类型的bean都将被封装为spy。如果未定义现有bean,则将添加新bean。

因此,主要区别是@SpyBean是Spring Boot特定注释,而@Spy是Mockito本身的一部分。@SpyBean@Spy基本上做相同的事情,但@SpyBean可以解决Spring特定的依赖关系,例如@Autowired,而@Spy只能创建带有空构造函数的对象。


那么,@SpyBean 将从已经存在于 Spring 容器中的实例加载 bean,而 @Spy 则会创建一个全新的对象,无论它是否已经存在于 Spring 容器中? - LiTTle
1
@Spy 的作用和你说的一样,但是对于 @SpyBean,文档中说: “上下文中相同类型的所有 bean 都将被包装为 spy。如果没有定义现有的 bean,则会添加一个新的 bean。” - csenga

1
在测试过程中,我注意到SpyBean会导致某些值在测试之间被传递,而Spy始终从干净的状态开始。在我的情况下,我在一个最初有自动装配组件的类上设置了@SpyBean。但是,在我重构这个类以删除它们后,我没有改变测试类,结果出现了意外的失败。
Class1 {
boolean boo;

myMethodA() {
    if (something) {
        boo=true;
    }
}

myMethodB() {
    if (boo) {
      doThis();
    } else { 
      doThat();
    }
  }
}

Test1和Test2都使用了@SpyBean Class1。两个测试用例都在隔离环境中成功运行,但当作为套件运行时,如果Test1运行后运行Test2,则会失败。

Test1在Class1中设置了一个布尔值为true,在Test2运行时仍然为true。这导致Test2失败,因为它期望布尔值为false。将@Spy更改为Class1会将布尔值重置为false,并使两个测试用例通过。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接