Mockito:使用@InjectMocks时模拟被测试方法调用的相同类的方法

ten*_*gen 1 java mockito

我有一个要测试的类,它具有多个外部依赖项和几个内部方法。我想编写一个测试MethodA,但没有方法A的内部调用来MethodB进行实际锻炼MethodB。我想模拟/存根MethodB并返回特定的内容。通常我会使用when/thenReturn它,但是它的行为却不像我预期的那样-在创建模拟本身时,它实际上跳入了方法B。

MyService.java

@Service
public class MyService {

  @Autowired
  private ServiceA serviceA;

  @Autowired
  private ServiceB serviceB;

    public SomeObject methodA() {
      // some logic using serviceA.method and serviceB.method that creates "output"
      SomeObject someObject = methodB(output);
      return someObject;
    }

    public SomeObject methodB(SomeObject someObject) {
      // deep mysteries done here to someObject
      return someObject 
    }
}
Run Code Online (Sandbox Code Playgroud)

MyServiceTest.java

public class MyServiceTest {

  @Mock
  private ServiceA serviceA;

  @Mock
  private ServiceB serviceB;

  @InjectMocks
  private MyService myService;

  @Before
  public void setUp() throws Exception {
    MockitoAnnotations.initMocks(this);
  }

  @Test
  public void methodATest() {
    when(serviceA.method()).thenReturn(stuff);
    when(serviceB.method()).thenReturn(otherStuff);

    // here is what I would like to do
    when(myService.methodB()).thenReturn(mockedSomeObject); //<- doesn't work

    assertThat(myService.methodA().getSomeObjectProperty())
        .isEqualTo("property");
  }
}
Run Code Online (Sandbox Code Playgroud)

我看过使用手动模拟MyService该类的解决方案Mockito.mock(MyService.class),但是(因为上面的示例显然是人为设计的)我的实际类具有相当多的外部依赖关系,我更喜欢一个仍然允许我模拟@Mock用于的服务的解决方案。@Autowired依赖关系和@InitMocks被测类,除非完全不可能。

我试过了:

Mockito.doReturn(mockedSomeObject).when(myService.methodB(any(SomeObject.class));
Run Code Online (Sandbox Code Playgroud)

但这在为该方法创建模拟程序时也会步入MethodB,这是不应该发生的。

在此先感谢您的帮助!

lra*_*hod 7

尝试将@Spy添加到InjectMocks,并使用该对象以稍有不同的语法“期望”它们。

import org.mockito.Spy;

 @InjectMocks
 @Spy
 private MyService myService; 
Run Code Online (Sandbox Code Playgroud)

现在模拟服务调用

 Mockito.doReturn(mockedSomeObject).when(myService).methodB();
Run Code Online (Sandbox Code Playgroud)

还要将其他模拟调用更改为此

Mockito.doReturn(stuff).when(serviceA).method();
Mockito.doReturn(otherStuff).when(serviceB).method();
Run Code Online (Sandbox Code Playgroud)