好的,所以我再次被Mockito困住了。情况如下:
我有一个超级类和一个子类:
class Parent {
protected void insertData() {
// Here is some database related stuff
someObject.storeData();
}
}
class Child extends Parent {
private String name;
public void printHierarchy(int x) {
if (x > 1) {
insertData()
} else {
System.out.println("Child");
}
}
}
在我的单元测试课程中,我正在测试Child
类printHierarchy()
方法:
@RunWith(SpringJUnit4ClassRunner.class)
public class ChildTest {
@InjectMocks // To inject mock objects
private Child child = new Child();
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
// This is where the issue is
doNothing().when(child).insertData();
}
@Test
public void testPrintHierarchy() {
child.printHierarchy(5);
// Here also
verify(child, times(1)).insertData();
}
}
问题是,如何验证是否insertData()
调用了Child#printHierachy()
方法?
当我尝试上面的代码时,我收到错误:
Argument passed to when() is not a mock!
当然,child
不是模拟。我正在测试那堂课。但是我该如何解决这个问题?
不,我没有发现任何重复。一个问题非常相似,但它对我没有帮助。
答案 0 :(得分:3)
您需要使用spy()
。以下代码有效:
public final class Bin
{
@Test
public void spyMe()
{
final Child c = spy(new Child());
doNothing().when(c).printParent();
c.printHierarchy(1);
verify(c).printParent();
}
}
class Parent {
protected void printParent() { System.exit(0);}
}
class Child extends Parent {
private String name;
public void printHierarchy(int i) {
if (i > 0)
printParent();
}
}
答案 1 :(得分:1)
方法printHierachy()
是否调用方法printParent()
肯定是方法printHierachy()
的实现细节,因此不应进行测试。单元测试应检查方法是否具有所需的输出。
对于打印方法,检查打印输出的格式是可行的。对于更新数据库的方法,请检查数据库是否包含预期值。对于以指定方式操作域模型对象的方法,请检查域对象是否处于正确状态。等等。
答案 2 :(得分:1)
我认为你需要为孩子使用间谍而不是模拟。
答案 3 :(得分:0)
我认为错误可能是概念性的。如果Child
扩展Parent
,那么Parent
的方法就是实施的一部分,即被测系统。
如果Parent
需要独立于Child
进行模拟,那么您可能应该使用合成而不是继承:
public class Child {
private Parent parent;
public void printHierarchy() {
parent.printParent();
}
// setters/getters
}
现在Parent
是可模拟的,您可以测试是否调用printParent()
。
如果类层次结构在概念上是正确的,则不需要测试内部实现细节(即接口/公共方法调用其他方法)。您不关心实施细节。