我正在编写一个使用JUNIT + Mockito测试方法的单元测试:
public someObject methodUnderTest(){
SomeObject obj = SomeAbstractClass.someMethod();
if(obj!=null){
obj.someOtherMethod();
}
return someThing;
}
我想在上面的代码片段中提到的abstract Class "SomeAbstractClass"
上模拟调用,这样我就可以验证对“obj”的调用,如:
verify(SomeAbstractClass).someMethod();
verify(obj).someOtherMethod();
我尝试使用类似的mockito功能: Mockito.CALLS_REAL_METHODS Mockito.RETURNS_MOCKS
但由于SomeAbstractClass无法使用的依赖项,它们无法正常工作。
注意:
1)SomeObject是一个接口。
2)我需要一种技术来测试上面的代码片段。我被限制使用上面的代码片段,无法更改代码片段。
答案 0 :(得分:2)
您可以使用PowerMock来模拟静态和最终方法。
答案 1 :(得分:2)
听起来问题是您对CALLS_REAL_METHODS的使用正在应用于整个类,您真正想要模拟特定方法(即进行“部分模拟”)。这里有两个选项,一个使用thenCallRealMethod
,一个使用CALLS_REAL_METHODS
,然后专门模拟您需要的调用:
public void testMethodUnderTest_mockSpecificThings() {
SomeAbstractClass myAbstractClass = Mockito.mock(SomeAbstractClass.class);
SomeAbstractClass myObject = Mockito.mock(SomeObject.class);
when(myAbstractClass.someMethod()).thenReturn(foo);
when(myAbstractClass.methodUnderTest()).thenCallRealMethod();
myAbstractClass.methodUnderTest();
verify(myAbstractClass).someMethod();
verify(myObject).someOtherMethod();
}
public void testMethodUnderTest_makeSpecificRealCalls() {
SomeAbstractClass myAbstractClass =
Mockito.mock(SomeAbstractClass.class, CALLS_REAL_METHODS);
SomeAbstractClass myObject = Mockito.mock(SomeObject.class);
// overrides the default answer
when(myAbstractClass.someMethod()).thenReturn(myObject);
myAbstractClass.methodUnderTest();
verify(myAbstractClass).someMethod();
verify(myObject).someOtherMethod();
}
预先警告SomeAbstractClass实际上从未实例化,因此如果您依赖抽象类构造函数中的任何行为,例如变量初始化 - 包括声明字段的内联初始化 - 您将需要自己明确地进行这些调用。
答案 2 :(得分:1)
使用匿名类:
public interface SomeObject {
public Object someOtherMethod();
}
public abstract class SomeAbstractClass {
abstract SomeObject someMethod();
}
@Test
public void test() {
SomeAbstractClass target = new SomeAbstractClass() {
SomeObject someMethod() {
// some impl
SomeObject someObject = new SomeObject() {
public Object someOtherMethod() {
// some other impl
}
};
return someObject;
}
};
// now test target
}
答案 3 :(得分:1)
假设:如果您编写单元测试,我猜您仍然可以稍微修改测试方法。
解决方案:
public someObject methodUnderTest() { SomeObject obj = getSomeObject(); if(obj!=null){ obj.someOtherMethod(); } return someThing; } protected SomeObject getSomeObject() { return SomeAbstractClass.someMethod(); }
private ClassUnderTest classUnderTest; @Before public void setUp() { classUnderTest= new ClassUnderTest(); classUnderTest = Mockito.spy(classUnderTest); } @Test public void test() { SomeObject someObject = Mockito.mock(SomeObject.class); when(classUnderTest.getSomeObject()).thenReturn(someObject); classUnderTest.methodUnderTest(); verify(someObject).someOtherMethod(); } @Test public void testNull() { when(classUnderTest.getSomeObject()).thenReturn(null); classUnderTest.methodUnderTest(); verify(something); }