在正在测试的同一个类中模拟私有方法 [英] Mock private method in the same class that is being tested

查看:100
本文介绍了在正在测试的同一个类中模拟私有方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a Java class named, MyClass, that I want to test with JUnit. The public method, methodA, that I want to test calls a private method, methodB, in the same class to determine which conditional path to follow. My goal is to write JUnit tests for the different paths in methodA. Also, methodB calls a service, so I do not want it to actually be executed when I run the JUnit tests.

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

What is the best way to mock methodB and control its return so that I can test different paths for 'methodA'?

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

I prefer to use JMockit when writing mocks, so I am specifically interested in any answer that applies to 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;
    }

}

这是我到目前为止所拥有的:

This is what I have so far:

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的部分模拟):

To give the answer you asked for (using JMockit's partial mocking):

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 ):

However, I would not recommend doing it like that. In general, private methods should not be mocked. Instead, mock the actual external dependency of your unit under test (the CustomObject in this case):

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));
    }
}

这篇关于在正在测试的同一个类中模拟私有方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆