我有一个类扩展了另一个我不拥有的类。我的类用于计算父类的许多调用中的一些指标。有没有办法可以在单元测试中模拟父类(同时保留我孩子的逻辑),以确保针对我的孩子的调用始终“通过”包裹父母?
代码
Class SlowClass {
public Object doFoo(Object obj) {
//...
}
public Object doBar(Object obj) {
//...
}
// Many more methods I don't care about.
}
Class SlowClassWrapper extends SlowClass {
public Object doFoo(Object obj) {
//...
Object toReturn = super.doFoo(obj)
//...
return toReturn;
}
public Object doBar(Object obj) {
//...
Object toReturn = super.doFoo(obj)
//...
return toReturn;
}
}
我想以某种方式模拟SlowClass.doFoo
,以便SlowClassWrapper.doFoo
在没有实际拨打电话的情况下调用其父母。然后,我想确认obj
未完成,SlowClass.doFoo
的回复没有受到影响。
答案 0 :(得分:4)
一般来说,这不是模拟框架可以在Java中愉快地做的事情。您可能需要考虑重构代码以使用组合而不是继承。然后,您可以将SlowClass实例注入包装器的构造函数中,通过常规模拟可以轻松测试。
对于它的价值,Mockito和PowerMock都不能嘲笑超级方法:见this answer和this discussion。
答案 1 :(得分:1)
我会做那样的事情:
public class SlowClassWrapper {
/** wrapped parent */
public final SlowClass parent;
public SlowClassWrapper() {
this(new SlowClass());
@VisibleForTesting
protected SlowClassWrapper(SlowClass parent) {
this.parent = parent;
}
public Object doFoo(Object obj) {
//...
Object toReturn = parent.doFoo(obj)
//...
return toReturn;
}
public Object doBar(Object obj) {
//...
Object toReturn = parent.doFoo(obj)
//...
return toReturn;
}
}
使用Mockito和JUnit
@RunWith(MockitoJUnitRunner.class)
public class SlowClassWrapperTest {
/** parent mock */
@Mock
private SlowClass parentMock;
/** instance under tests */
private SlowClassWrapper instance;
@Before
public void setUp() {
this.instance = new SlowClassWrapper(this.parentMock);
}
@Test
public void testDoFoo() {
final Object obj1 = new Object();
final Object obj2 = new Object();
Mockito.doReturn(obj2).when(this.parentMock).doFoo(Matchers.any());
assertEquals(obj2, this.instance.doFoo(obj1));
Mockito.verify(this.parentMock).doFoo(obj1);
Mockito.verifyNoMoreInteractions(this.parentMock);
}
@Test
public void testDoBar() {
final Object obj1 = new Object();
final Object obj2 = new Object();
Mockito.doReturn(obj2).when(this.parentMock).doBar(Matchers.any());
assertEquals(obj2, this.instance.doBar(obj1);
Mockito.verify(this.parentMock).doBar(obj1);
Mockito.verifyNoMoreInteractions(this.parentMock);
}
}
(未经测试)