在 class 上模拟内部实例进行测试

Mock inner instance on class to test

我正在使用 Mockito 编写一些测试用例。我遇到了一个问题,我在网上寻找解决方案,但没有找到明确的答案。

给定以下 类 我想模拟对该方法的所有调用 getMessageClassB 此类型的所有实例上。

public class ClassA {
    private ClassB b = new ClassB("From ClassA");

    int methodToTest() {
        System.out.println("methodToTest use instqnce ClassB " + b.getMessage());
        return -1;
    }
}

class ClassB {
    private String message;

    /**
     * 
     */
    public ClassB(final String msg) {
        this.message = msg;
    }

    /**
     * @return the message
     */
    public String getMessage() {
        return message;
    }

    /**
     * @param message the message to set
     */
    public void setMessage(final String message) {
        this.message = message;
    }
}

我试过但没有用的是:

public class ClassATest {

    @Test
    public void testOK1() {
       ArgumentCaptor<ClassB> captorClassB = ArgumentCaptor.forClass(ClassB.class);
       Mockito.doReturn("MOCK message").when(captorClassB.capture()).getMessage();

       ClassA a = new ClassA();
       assertTrue(a.methodToTest() == -1);
    }

    @Test
    public void testOK2() {
        Mockito.doReturn("MOCK message").when(Mockito.any(ClassB.class)).getMessage();

        ClassA a = new ClassA();
        assertTrue(a.methodToTest() == -1);
    }
}

我的问题首先是可不可以。其次,如何?我要重构代码吗?

您应该在 ClassA 的构造函数中传递 ClassB,而不是创建新的 B 类。通过这种方式,您可以传递模拟的 ClassB 实例并验证它是否被调用。

public class ClassA { 
    ClassB classB;

    public ClassA(ClassB classB){
        this.classB = classB;
    }
}

最后我制定了如下解决方案。如果此方法有一些缺点,请指出。

public class ClassA {
    private ClassB b = new ClassB("From ClassA");

    int methodToTest() {
        System.out.println("methodToTest use instqnce ClassB " + getClassB().getMessage());
        return -1;
    }

    /**
     * 
    */
    public ClassB getClassB() {
        return b;

   }
}



class ClassB {
    private String message;

    /**
     * 
     */
    public ClassB(final String msg) {
        this.message = msg;
    }

    /**
     * @return the message
     */
    public String getMessage() {
        return message;
    }

    /**
     * @param message the message to set
     */
    public void setMessage(final String message) {
        this.message = message;
    }
}


public class ClassATest {

    @Test
    public void testOK() {
        ClassA a = new ClassA();

        ClassB b = new ClassB("MOCK message");

        ClassA spyA = spy(a);

        Mockito.doReturn(b).when(spyA).getClassB();

        assertTrue(spyA.methodToTest() == -1);
    }

}