我正在使用Mockito进行一些单元测试。我有以下课程:
public class Base {
public void say() {
System.out.println("Base"); // some work in the base class
}
}
public class Derived extends Base {
@Override
public void say() {
super.say(); // do the base class work
System.out.println("Derived"); // some additional work in the derived class
}
}
现在我想测试Derived类的say()
方法,同时模拟base say()方法。我遵循了这里的建议:Mockito如何只模拟超类的方法的调用,我现在有了。
public class DerivedTest {
@Test
public void testSay() {
Derived obj = Mockito.spy(new Derived());
Mockito.doNothing().when((Base)obj).say();
obj.say();
// assert only "Derived" was output
}
}
但这并不起作用,因为它模拟了基类和派生类的实现。我只想测试派生类中的额外逻辑。
我该怎么做。
更新:我的解决方案
由于我无法按照建议更改基类,所以我修改了派生类,以在一个单独的方法中提取所有额外的逻辑,并测试了该方法。
public class Derived extends Base {
@Override
public void say() {
super.say(); // do the base class work
doAdditionalWork(); // some additional work in the derived class
}
void doAdditionalWork() {
System.out.println("Derived");
}
}
public class DerivedTest {
@Test
public void testDoAdditionalWork() {
Derived obj = new Derived();
obj.doAdditionalWork();
// assert only "Derived" was output
}
}
这意味着我仍然没有测试派生的say()方法,但考虑到那里的逻辑现在很简单,我希望我可以原谅这一点。另一个缺点是,对于doAdditionalWork()方法,我不能有比package private更严格的可见性。
当您spy
一个对象时,您完全替换了为其定义mock行为的方法的实现。所以,正如你在问题中指出的,这是行不通的。
其中一个技巧是提取additionalBehavior()
方法,并只测试它,而不进行间谍或嘲笑:
public class Base {
public void say() {
System.out.println("Base"); // some work in the base class
additionalBehavior();
}
protected void additionalBehavior() {
// No implementation. Alternatively - make it abstract
}
}
public class Derived extends Base {
@Override
protected void additionalBehavior() {
System.out.println("Derived"); // some additional work in the derived class
}
}
public class DerivedTest {
@Test
public void testAdditionalBehavior() {
Derived obj = new Derived();
obj.additioanlBehavior();
// assert that "Derived" was the output
}
}