使用"this"关键字调用的 Mockito 存根方法



我必须测试某些SLSB的方法,该方法在当前对象上调用另一种方法(使用 this this 关键字),我需要以某种方式对其进行固定。

考虑以下简化代码:

@Local
public interface SomeService{
    public int someMethod();
    public int anotherMethod();
}
@Stateless()
public class SomeServiceImpl{
    @EJB
    private SomeDAO sDAO;
    public SomeServiceImpl(){}
    public SomeServiceImpl(SomeDAO sDAO){
         this.sDAO = sDAO;
    }
    @Override
    public int someMethod(){
        int dbValue = sDAO.getSomeDBValue(); // 1st stub required here
        return dbValue + this.anotherMethod(); // 2nd stub required here
    }
    @Override
    public int anotherMethod(){
         return 5;
    }
}

到stub getsomedbvalue()方法我可以用@mock和@injectMocks注释将模拟注入此类,但我不知道如何正确地stub eyterMethod()。要存根它,我需要在模拟对象上进行操作,因此我尝试将当前对象作为参数传递,而在测试中只需通过模拟对象即可。例如,如果我的方法看起来像这样(无需使用dao方法)。

@Override
public int someMethod(SomeServiceImpl sS){ 
    return sS.anotherMethod(); 
}

我用手动创建的模拟测试看起来像这样:

@Test
public void someMethodTest() throws Exception {
    SomeServiceImpl sS = mock(SomeServiceImpl.class);
    when(sS.someMethod(any(SomeServiceImpl.class))).thenCallRealMethod();
    when(sS.anotherMethod()).thenReturn(5);
    assertEquals(5, sS.someMethod(sS));
}

方法是在模拟对象上调用的,对对象本身的引用将传递为参数,而另一个method则是固定的。它起作用了,但似乎很丑陋,如果需要使用这样的注释来对我的dao进行模拟怎么办:

@RunWith(MockitoJUnitRunner.class)
public class SomeClassTest{
    @Mock
    SomeDAO sDAO;
    //@Mock //I can't use those 2 annotations at once
    @InjectMocks
    SomeServiceImpl sS; 
    @Test
    public void someMethodTest() throws Exception {
        //...   
    }
}

我了解@InjectMocks注释用于指示@mock注释的模拟的类,但是对于我的丑陋解决方案,我也需要SomeServiceImpl才能模拟。

我的解决方案甚至接近纠正吗?我应该如何固定另一个方法()正确测试somemethod()?通过模拟的类实例,我在方法参数中测试了哪种方法是一个好主意?如果是,我应该如何处理用注释创建模拟?

在测试相同类的另一种方法时,您不应模拟方法。从理论上讲,您可以做到这一点(使用Mokito间谍例如)。

从这个意义上讲,您正在以错误的层次接近此问题:实际上,您不应该在测试中测试的方法中使用哪些其他方法。您会看到,您想 test someMethod()确实履行其合同。如果需要在您的生产环境中打电话给anotherMethod() ...您的单位测试有多有价值,那么当它模拟anotherMethod()时?!

另一个想法:您将问题分开,然后将anotherMethod()零件移至其自己的X类中。然后可以模拟该实例。

最新更新