如何模拟 SpyBean 的各个方法?

Dan*_*Dan 6 java spring mocking mockito spy

我正在开发一个测试类,其中一个特定测试需要实际实现我正在模拟的服务类的方法。所以我想,为什么不在@SpyBean@MockBean需要的地方使用而不是使用实际的实现(不必做任何事情)并在我需要的地方使用模拟的实现(需要编写一行来设置模拟的方法) 。

我发现了这篇很棒且非常详细的博客文章,解释了如何实现这一点,“@SpyBean 来救援”部分。

唯一的问题是它不起作用,使用了真正的实现并且这些测试成功了,但是模拟的方法没有启动。我正在使用 Mockito 2.21.0 和 Spring Framework 5.1.0。现在我为此目的使用单独的测试类,但我想弄清楚如何以正确的方式做到这一点。

我所做的事情与此博客上的示例几乎完全相同:

@SpringBootTest(classes = TestclassAA.class)
class TestclassAA {
@SpyBean
private XXService xxService;

private ClassUsingXXService testee;

@Test
void test1 {
   // ..
   // use mocked implementation of save() -> does not work, real method called
   doReturn(new XXRequestModel()).when(xxService).save(any(XXModel.class));
   var result = testee.doSomething();
   //.. 
}

@Test
void test2 {
  // ..
  // use actual implementation of save() -> works, real method called
  var result = testee.doSomething();
  //.. 
}
Run Code Online (Sandbox Code Playgroud)

基本上我收到的错误消息暗示我所做的事情对于间谍来说根本不可能:

org.mockito.exceptions.misusing.NotAMockException: 
Argument passed to when() is not a mock!
Example of correct stubbing:
doThrow(new RuntimeException()).when(mock).someMethod();

E.g. thenReturn() may be missing.
Examples of correct stubbing:
when(mock.isOk()).thenReturn(true);
when(mock.isOk()).thenThrow(exception);
doThrow(exception).when(mock).someVoidMethod();

Hints:
1. missing thenReturn()
2. you are trying to stub a final method, which is not supported
3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed
Run Code Online (Sandbox Code Playgroud)

有人知道如何做到这一点吗?