当前位置: 首页 > 知识库问答 >
问题:

使用JMockit模拟被测类的私有方法

辛可人
2023-03-14
public class ClassToTest 
{
    public void methodToTest()
    {
        Integer integerInstance = new Integer(0);
        boolean returnValue= methodToMock(integerInstance);
        if(returnValue)
        {
            System.out.println("methodToMock returned true");
        }
        else
        {
            System.out.println("methodToMock returned true");
        }
        System.out.println();
    }
    private boolean methodToMock(int value)
    {
        return true;
    }
}
import org.junit.Test;
import static mockit.Deencapsulation.*;

import mockit.*;
public class TestAClass 
{
    @Tested ClassToTest classToTestInstance;
    @Test
    public void test1()
    {

        new NonStrictExpectations(classToTestInstance)
        {
            {
                invoke(classToTestInstance, "methodToMock", anyInt);
                returns(false);
                times = 2;

                invoke(classToTestInstance, "methodToMock", anyInt);
                returns(true);
                times = 1;

            }
        };

        classToTestInstance.methodToTest();
        classToTestInstance.methodToTest();
        classToTestInstance.methodToTest();

    }
}

我这样做是为了得到想要的结果

    final StringBuffer count = new StringBuffer("0");
    new NonStrictExpectations(classToTestInstance)
    {

        {
            invoke(classToTestInstance, "methodToMock", anyInt);
            result= new Delegate() 
            {
                boolean methodToMock(int value)
                {                   
                    count.replace(0, count.length(), Integer.valueOf(Integer.valueOf(count.toString())+1).toString());
                    if(Integer.valueOf(count.toString())==3)
                    {
                        return true;
                    }
                    return false;
                }
            };

        }
    };

共有1个答案

邢冷勋
2023-03-14

使用预期和deencapsulation.invoke()的组合,可以部分模拟测试对象:

import org.junit.Test;
import static mockit.Deencapsulation.*;
import mockit.*;

public class TestAClass
{
    public static class ClassToTest 
    {
        public void methodToTest()
        {
            boolean returnValue = methodToMock(0);
            System.out.println("methodToMock returned " + returnValue);
        }

        private boolean methodToMock(int value) { return true; }
    }

    @Tested ClassToTest classToTestInstance;

    @Test
    public void partiallyMockTestedClass() {
        new Expectations(classToTestInstance) {{
            invoke(classToTestInstance, "methodToMock", anyInt);
            result = false;
            times = 2;
        }};

        classToTestInstance.methodToTest();
        classToTestInstance.methodToTest();
        classToTestInstance.methodToTest();
    }
}

上面的测试打印:

methodToMock returned false
methodToMock returned false
methodToMock returned true

当然,一般来说,我们应该避免嘲笑private方法。也就是说,我在实践中发现,这样做有时是有用的,通常是当你有一个私人方法,它做了一些非琐碎的事情,并且已经被另一个测试测试了;在这种情况下,在第二个测试中模仿私有方法(对于不同的公共方法或通过同一公共方法的不同路径)可能比设置必要的输入/条件容易得多。

@Test
public void partiallyMockTestedClass() {
    new NonStrictExpectations(classToTestInstance) {{
        invoke(classToTestInstance, "methodToMock", anyInt);
        returns(false, false, true);
    }};

    classToTestInstance.methodToTest();
    classToTestInstance.methodToTest();
    classToTestInstance.methodToTest();
}
@Test
public void partiallyMockTestedClass() {
    new NonStrictExpectations(classToTestInstance) {{
        invoke(classToTestInstance, "methodToMock", anyInt);

        result = new Delegate() {
           boolean delegate() {
               boolean nextValue = ...choose next return value somehow...
               return nextValue;
           }
        }
    }};

    classToTestInstance.methodToTest();
    classToTestInstance.methodToTest();
    classToTestInstance.methodToTest();
}
 类似资料:
  • 上面还有第二个问题。当我在Expects块中定义mock类时(如上),似乎只调用了构造函数,而不是,因此没有正确初始化对象。我通过将它移到方法中并在那里实例化该类来解决这个问题。看起来是这样的: 因此,这似乎得到了要调用的正确构造函数,但似乎还在调用。有什么见解吗?

  • 问题内容: 我在类中使用 私有静态最终LOGGER 字段,并且我希望 LOGGER.isInfoEnabled() 方法返回 false 。我如何通过使用Mockito或jMockit模拟静态的final字段 我的课是: 其junit为: 当我运行它的结果是: 我是jmockit的新手,我希望上述junit案例能够成功运行。而且我必须使用JMockit或Mockito,不能使用Powermocki

  • 我在我的类中使用私有静态final LOGGER字段,我希望LOGGER.isInfoEnabled()方法返回false。如何使用mockito或jMockit模拟静态final字段 我的课是: 当我运行它时,结果是: 我是jmockit新手,我希望上面的junit案例能够成功运行。我只能用JMockit或mockito,不能用powermockito。请帮帮忙。

  • 我有一门课看起来像这样: 我想使用Mockito和Powermock为此编写一个单元测试。我知道我可以这样模仿私有方法: 但是我如何告诉它抛出异常呢?我知道会是这样的: 那里有什么? 请注意,异常是一个私有内部类,因此我不能只执行,因为从单元测试中无法访问。