Mockito:使用@InjectMocks时模拟被测试方法调用的相同类的方法 [英] Mockito: mocking a method of same class called by method under test when using @InjectMocks

查看:208
本文介绍了Mockito:使用@InjectMocks时模拟被测试方法调用的相同类的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

MyService.java

  @Service公共类MyService {@Autowired私人服务A serviceA;@Autowired私人ServiceB serviceB;公共SomeObject methodA(){//使用serviceA.method和serviceB.method创建输出"的一些逻辑SomeObject someObject = methodB(输出);返回someObject;}公共SomeObject methodB(SomeObject someObject){//这里对someObject造成了深深的奥秘返回someObject}} 

MyServiceTest.java

 公共类MyServiceTest {@嘲笑私人服务A serviceA;@嘲笑私人ServiceB serviceB;@InjectMocks私有MyService myService;@前公共无效setUp()引发异常{MockitoAnnotations.initMocks(this);}@测试公共无效methodATest(){when(serviceA.method()).thenReturn(stuff);when(serviceB.method()).thenReturn(otherStuff);//这是我想做的when(myService.methodB()).thenReturn(mockedSomeObject);//<-不起作用assertThat(myService.methodA().getSomeObjectProperty()).isEqualTo("property");}} 

我已经研究了使用 Mockito.mock(MyService.class)手动模拟 MyService 类的解决方案,但是(因为上面的示例显然是人为设计的)实际的类具有很多外部依赖项,我更喜欢一个解决方案,该解决方案仍然允许我使用 @Mock 来模拟 @Autowired 依赖项和 @的服务除非根本不可能,否则将InitMocks 用于所测试的类.

我尝试过:

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

但是在为该方法创建模拟程序时,这也会进入到MethodB中.

提前感谢您的帮助!

解决方案

尝试将@Spy添加到InjectMocks,并使用该对象以略有不同的语法期望"它们.

import org.mockito.Spy;

  @InjectMocks@间谍私有MyService myService; 

现在模拟服务调用

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

也将另一个模拟调用更改为此

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

I have a class I want to test that has several external dependencies, and a couple internal methods. I would like to write a test for MethodA, but not have Method A's internal call to MethodB to actually exercise MethodB. I'd like to mock/stub MethodB and return something specific instead. Usually I'd use when/thenReturn but it doesn't behave like I expect - it actually jumps into Method B while creating the mock itself.

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

I've looked at solutions that manually mock the MyService class with Mockito.mock(MyService.class), but (as the above example is obviously contrived) my actual class has quite a few external dependencies and I'd prefer a solution that still allows me to mock the service using @Mock for the @Autowired dependencies and @InitMocks for the class under test, unless it's simply not possible.

I've tried:

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

but that also steps into MethodB when creating the mock for that method, which shouldn't be happening.

Thanks in advance for the help!

解决方案

Try Adding @Spy to your InjectMocks and use the object to "expect" them in a slightly different syntax.

import org.mockito.Spy;

 @InjectMocks
 @Spy
 private MyService myService; 

And now mock the service call

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

Also change the other mock call to this

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

这篇关于Mockito:使用@InjectMocks时模拟被测试方法调用的相同类的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆