我正在寻找一种在其子构造函数的单元测试中模拟或以其他方式存储父类功能的方法。 Parent类本身设计不佳,但由于合同协议而无法触及。我们已经在使用PowerMockito,但PowerMock(EasyMock)也在批准的库列表中。这是简化的代码,以及我迄今为止在单元测试工作中的最佳尝试:
/**
* The class Parent is locked
*/
public class Parent {
private final Integer x;
private final Integer y;
public Parent(Integer x) {
this.x = x;
this.y = loadY();
}
private int loadY() {
// Actual code loads a bunch of stuff from DB
throw new RuntimeException();
}
protected Integer getSum() {
return x+y;
}
}
/**
* This code is not locked, but Child MUST extend Parent and foo MUST be final.
*/
public class Child extends Parent{
private final Integer foo;
public Child(int x) {
super(x);
foo = getSum();
}
public Integer getFoo() {
return foo;
}
}
@RunWith(PowerMockRunner.class)
@PrepareForTest({Child.class, Parent.class})
public class ChildTest {
@Mock
private Parent par;
@Test
public void testGetFoo() throws Exception {
MemberModifier.suppress(MemberMatcher.constructor(Parent.class, Integer.class));
PowerMockito.whenNew(MemberMatcher.constructor(Parent.class)).withNoArguments().thenReturn(par);
Mockito.when(par.loadY()).thenReturn(new Integer(3));
Mockito.when(par.getSum()).thenReturn(7);
Child child = new Child(4);
Assert.assertEquals(new Integer(7), child.getFoo());
}
}
我能够并且愿意编辑类Child,只要它继续扩展Parent并且foo是final,但我无法以任何方式编辑Parent。模拟对getSum()的调用将更为理想,因为这将允许验证该调用(此处不相关,但可能在其他情况下)。仍然,模拟loadY()或设置child.y的状态似乎是可以接受的,但设置child.foo似乎不正确。我花了一大部分时间在网站和eclipse之间来回反复尝试解决这个问题,但到目前为止,每次运行都会产生可预期的RTE或NPE。任何想法?