Spring (@SpyBean) vs Mockito(@Spy)

Spring (@SpyBean) vs Mockito(@Spy)

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

使用 @SpyBean 而不是 @Spy 会使我的 tests 失败。

@Spy doc 说:

A field annotated with @Spy can be initialized explicitly at declaration point. Alternatively, if you don't provide the instance Mockito will try to find zero argument constructor (even private) and create an instance for you.

@SpyBean doc 说:

Annotation that can be used to apply Mockito spies to a Spring ApplicationContext.

All beans in the context of the same type will be wrapped with the spy. If no existing bean is defined a new one will be added.

所以主要区别是 @SpyBean 是一个 Spring 引导特定注释,但 @Spy 是 Mockito 本身的一部分。 @SpyBean@Spy 基本上做同样的事情,但是 @SpyBean 可以解决 Spring 特定的依赖关系,例如@Autowired, @Spy 只能用空构造函数创建对象。

我在测试期间注意到的一点是,SpyBean 会导致某些值在测试之间被转移,而 Spy 总是从一个干净的状态开始。在我的例子中,我在 class 上设置了 @SpyBean,该 class 最初具有自动装配的组件。但是在我重构 class 以删除它们之后,我没有更改测试 classes 并且我遇到了意外失败。

Class1 {
boolean boo;

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

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

Test1 和Test2 都使用了@SpyBean Class1。 Test1 和 Test2 运行 都成功隔离,但是当 运行 作为一个套件时,如果 Test2 在 Test1.运行 之后

就会失败

Test1将Class1中的一个布尔值设置为true,Test2运行时仍然为true。这导致 Test2 失败,因为它期望布尔值是假的。更改为 @间谍类1 导致布尔值被重置为 false 并且两个测试都通过了。