我必须测试一些SLSB的方法,它在当前对象上调用另一个方法(使用 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注释向这个类注入mock,但我无法弄清楚如何正确地存根anotherMethod()。要存根,我需要在模拟对象上确实这样做,所以我尝试将参考传递给当前对象作为参数,并在测试中传递模拟对象。 例如,如果我的方法看起来像这样(不需要存根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));
}
在模拟对象上调用方法,对对象本身的引用作为参数传递,而另一个方法被存根。它工作但似乎非常难看的解决方案,如果需要使用这样的注释注入我的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进行模拟。
我的解决方案是否接近正确?我怎么想断开anotherMethod()来正确测试someMethod()?传递模拟的类实例是一个好主意,我在方法参数中测试哪个方法?如果是,我该如何处理创建带注释的模拟?