【问题标题】:Mockito: mocking a method of same class called by method under test when using @InjectMocksMockito:在使用@InjectMocks 时模拟被测试方法调用的同一类的方法
【发布时间】:2018-06-04 15:19:29
【问题描述】:

我有一个要测试的类,它有几个外部依赖项和几个内部方法。我想为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 
    }
}

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");
  }
}

我查看了使用 Mockito.mock(MyService.class) 手动模拟 MyService 类的解决方案,但是(因为上面的示例显然是人为的)我的实际类有很多外部依赖项,我更喜欢一个仍然允许我使用 @Mock 来模拟服务,使用 @Autowired 依赖项和 @InitMocks 来模拟被测类,除非它根本不可能。

我试过了:

Mockito.doReturn(mockedSomeObject).when(myService.methodB(any(SomeObject.class));

但在为该方法创建模拟时也会进入 MethodB,这不应该发生。

提前感谢您的帮助!

【问题讨论】:

    标签: java mockito


    【解决方案1】:

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

    import org.mockito.Spy;

     @InjectMocks
     @Spy
     private MyService myService; 
    

    现在模拟服务调用

     Mockito.doReturn(mockedSomeObject).when(myService).methodB();
    

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

    Mockito.doReturn(stuff).when(serviceA).method();
    Mockito.doReturn(otherStuff).when(serviceB).method();
    

    【讨论】:

    • 谢谢 - 我已经单独尝试了这些更改,但从未一起尝试过 - 这非常有效!
    • 很高兴能帮到你。
    • @lrathod ,使用when(serviceA.method()).ThenReturn(stuff)doReturn(stuff).when(serviceA).method() 有什么区别??
    • @Eric,当您使用“间谍”时,您将需要使用后者。不过,在功能上两者都是一样的。
    【解决方案2】:

    您需要将您的对象标记为 Spy 或使用 MyClass objA=null; MyClass spy_objA=Powermockito.spy(objA) doReturn(what_you_want).when(spy_objA).method() 为它显式创建一个 Spy 对象

    编辑:可以找到您可能想要检查的类似问题 How to mock another method in the same class which is being tested?

    【讨论】:

    • 感谢您的想法 - 但是我宁愿不使用 PowerMockito,除非真的无法使用“常规”Mockito 来完成此操作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-17
    • 2013-06-04
    • 2015-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多