我有以下结构:
class Bar{
....
protected void restore(){
....
}
....
}
此课程由Foo
扩展如下:
class Foo extends Bar{
....
@Override
public void restore(){ //valid override
super.restore();
....
}
}
在我的jUnit测试中,我想测试一下,当调用foo.restore()
时,随后会调用super.restore()
。因此,下面是我的jUnit测试方法:
class FooTest{
@Tested
Foo _foo;
@Test
void testRestore(final Bar bar){
new Expectations(){{
bar.restore(); times = 1; // Error! bar.restore() not visible
}};
Deencapsulation.invoke(_foo,"restore");
}
}
不幸的是,我的测试无法编译。原因是1)父项的restore()
为protected
而2)FooTest
和Foo
一起存在于单独的项目(因此文件夹)与{{{ 1}}。
反正有没有达到预期的测试?我检查了jMockit tutorials(过去几个月多次)并没有看到类似的测试(在Google上进行搜索也是如此)。
更新
在回复的帮助下,我理解强制执行子类来调用Bar
并不是最好的做法,但这不是我的实现,我仍然必须测试它。我仍在寻找一种方法来强制执行我的jUnit测试,以检查对父母的调用是否正在进行。
答案 0 :(得分:4)
所以基本上你是在试图强制调用super并尝试允许子类化的契约?我认为由于动态调度将隐藏Java中的行为,因此不容易做到这一点。我不认为Mocking会抓住这个。
确保super被调用的方法是将超级和扩展分解为2种方法,如
class Foo {
public final void restore() {
//parent code...
doRestore();
}
protected void doRestore() {
//empty base implementation
}
}
class Bar extends Foo {
protected void doRestore() {
//do my subclass specific restore stuff here
}
}
答案 1 :(得分:1)
super.restore()
应该做些有用的事吗?一些具体的逻辑。在您的测试中,只需测试调用super.restore()
的结果即可。
另一种研究方法如下。在做任何事情之前的子类中,你实现了一个assert
确保超级正确地完成了它的工作。这是一个更强大的检查,并且是众所周知的Meyer的 Design by Contract 范例的一部分。在此上下文中,子类只是检查super.restore()
实现的后置条件在执行之前是否成立,并且使用assert
您知道它将在单元测试期间失败,但也会在应用程序的测试集成运行期间失败,例如< / p>
class Foo extends Bar{
....
@Override
public void restore(){ //valid override
super.restore();
assert super_restore_worked_ok_condition : "restore post-condition failed";
....
}
}
答案 2 :(得分:1)
以下测试应该有效:
public class FooTest
{
@Tested Foo _foo;
@Test
void restoreInFooCallsSuper(@Mocked final Bar bar)
{
new Expectations() {{
invoke(bar, "restore");
}};
_foo.restore();
}
}