Mockito Java中的模拟继承方法

Jud*_*han 5 java unit-testing mockito

我的班级结构如下:

public class MyParentClass {

    void doSomethingParent() {
        System.out.println("something in parent");
    }
}

public class MyClass extends MyParentClass {

    protected String createDummyRequest(Holder myHolder) {
        //...
        super.doSomethingParent();//I want to avoid this
        //...
        callingDB();
        return "processedOutput";
    }

    private void callingDB() {
        System.out.println("Calling to DB");
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我的单元测试:

public class UnitTest {

    public void testCreateDummyRequest() {
        //create my mock holder
        Holder mockHolder = new Holder();

        MyClass mockObj = Mockito.mock(MyClass.class);
        //mock doSomethingParent()
        //mock callingDB()

        //as mockObj is a fully mock, but I need to run my real method
        //Mockito.when(mockObj.createDummyRequest(mockHolder)).thenCallRealMethod();
        mockObj.createDummyRequest(mockHolder);
        //Problem: doSomethingParent() is getting called though I have mocked it
    }
}
Run Code Online (Sandbox Code Playgroud)

如何防止在我的方法中调用 super.doSomethingParent()?(我正在编写测试的方法)

Nic*_*tar 4

对于这个类结构,模拟和测试真的很困难。如果可能的话,我建议更改结构,因为在迷雾情况下,难以模拟和测试的类结构同样难以扩展和维护。

因此,如果您可以将类结构更改为类似于:

public class MyClass {

    private DoSomethingProvider doSomethingProvider;

    private DbConnector dbConnector;

    public MyClass (DoSomethingProvider p, DbConnector c) {
        doSomethingProvicer = p;
        dbConnector = c;
    }


    protected String createDummyRequest(Holder myHolder){
        //...
        doSomethingProvider.doSomethingParent();
        //...
        dbConnector.callingDB();
        return "processedOutput";
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用 DoSomethingProvider 和 DbConnector 的模拟轻松创建实例,瞧......

如果您无法更改类结构,则需要使用 Mockito.spy 而不是 Mockito.mock 来存根特定方法调用,但使用真实对象。

public void testCreateDummyRequest(){
    //create my mock holder
    Holder mockHolder = new Holder();

    MyClass mockObj = Mockito.spy(new MyClass());

    Mockito.doNothing().when(mockObj).doSomething();

    mockObj.createDummyRequest(mockHolder);
}
Run Code Online (Sandbox Code Playgroud)

注意:使用super关键字可以防止 Mockito 对该方法调用进行存根处理。我不知道是否有办法对 super 进行存根调用。如果可能(例如您没有重写类中的父方法),只需省略关键字即可。