java - 正在测试的同一类中的模拟私有(private)方法

标签 java unit-testing junit mocking jmockit

我有一个名为 MyClass 的 Java 类,我想用 JUnit 对其进行测试。我要测试的公共(public)方法 methodA 调用同一类中的私有(private)方法 methodB 以确定要遵循的条件路径。我的目标是为 methodA 中的不同路径编写 JUnit 测试。此外,methodB 调用一个服务,所以我不希望它在我运行 JUnit 测试时实际执行。

模拟 methodB 并控制其返回以便我可以测试“methodA”的不同路径的最佳方法是什么?

我更喜欢在编写模拟时使用 JMockit,因此我对适用于 JMockit 的任何答案特别感兴趣。

这是我的示例类:

public class MyClass  {

    public String methodA(CustomObject object1, CustomObject object2)  {

        if(methodB(object1, object2))  {
            // Do something.
            return "Result";
        }

        // Do something different.
        return "Different Result";

    }

    private boolean methodB(CustomObject custObject1, CustomObject custObject2)  {

        /* For the sake of this example, assume the CustomObject.getSomething()
         * method makes a service call and therefore is placed in this separate
         * method so that later an integration test can be written.
         */
        Something thing1 = cobject1.getSomething();
        Something thing2 = cobject2.getSomething();

        if(thing1 == thing2)  {
            return true;
        }
        return false;
    }

}

这是我目前所拥有的:

public class MyClassTest  {
    MyClass myClass = new MyClass();

    @Test
    public void test_MyClass_methodA_enters_if_condition()  {
        CustomObject object1 = new CustomObject("input1");
        CustomObject object2 = new CustomObject("input2");

        //  How do I mock out methodB here to return true?

        assertEquals(myClass.methodA(object1, object2), "Result");
    }

    @Test
    public void test_MyClass_methodA_skips_if_condition()  {
        CustomObject object1 = new CustomObject("input1");
        CustomObject object2 = new CustomObject("input2");

        //  How do I mock out methodB here to return false?

        assertEquals(myClass.methodA(object1, object2), "Different Result");
    }

}

谢谢!

最佳答案

给出您要求的答案(使用 JMockit 的部分模拟):

public class MyClassTest
{
    @Tested MyClass myClass;

    @Test
    public void test_MyClass_methodA_enters_if_condition() {
        final CustomObject object1 = new CustomObject("input1");
        final CustomObject object2 = new CustomObject("input2");

        new NonStrictExpectations(myClass) {{
            invoke(myClass, "methodB", object1, object2); result = true;
        }};

        assertEquals("Result", myClass.methodA(object1, object2));
    }

    @Test
    public void test_MyClass_methodA_skips_if_condition() {
        final CustomObject object1 = new CustomObject("input1");
        final CustomObject object2 = new CustomObject("input2");

        new NonStrictExpectations(myClass) {{
            invoke(myClass, "methodB", object1, object2); result = false;
        }};

        assertEquals("Different Result", myClass.methodA(object1, object2));
    }
}

但是,我建议这样做。通常,不应模拟 private 方法。相反,模拟被测单元的实际外部依赖性(在本例中为 CustomObject):

public class MyTestClass
{
    @Tested MyClass myClass;
    @Mocked CustomObject object1;
    @Mocked CustomObject object2;

    @Test
    public void test_MyClass_methodA_enters_if_condition() {
        new NonStrictExpectations() {{
            Something thing = new Something();
            object1.getSomething(); result = thing;
            object2.getSomething(); result = thing;
        }};

        assertEquals("Result", myClass.methodA(object1, object2));
    }

    @Test
    public void test_MyClass_methodA_skips_if_condition() {
        new NonStrictExpectations() {{
            object1.getSomething(); result = new Something();
            object2.getSomething(); result = new Something();
        }};

        assertEquals("Different Result", myClass.methodA(object1, object2));
    }
}

关于java - 正在测试的同一类中的模拟私有(private)方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19699122/

相关文章:

Java在列表中查找重复项

java - 无法从 boot_complete 接收器启动外部服务

javascript - Jest 模拟功能未按预期工作

java - 带有卡尺的 Junit 设置

java - 如何让 Eclipse 2018.09 默认使用 JUnit 4 测试运行器?

java - 当可以使用 SecureRandom 类时,为什么还要使用 Java 的 Random 类?

java - 如何将 JavaFX javafx.scene.shape.Path 的实例保存到文件

c - 如何捕捉对 exit() 的调用(用于单元测试)

c++ - QtCreator:部署单元测试

java - Camunda测试部署注释未部署