验证是否从正在测试的方法调用了继承的超类方法

时间:2014-03-19 13:29:54

标签: java spring mockito

好的,所以我再次被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");
        }

    }
}

在我的单元测试课程中,我正在测试ChildprintHierarchy()方法:

@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不是模拟。我正在测试那堂课。但是我该如何解决这个问题?

不,我没有发现任何重复。一个问题非常相似,但它对我没有帮助。

4 个答案:

答案 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()

如果类层次结构在概念上是正确的,则需要测试内部实现细节(即接口/公共方法调用其他方法)。您不关心实施细节。