JMockit:如何根据构造函数中给出的参数模拟方法?

Eya*_*oth 0 java jmockit mocking

我想使用JMockit模拟以下类:

public class A {

    private int n;

    public A(int n) {
        this.n = n;
    }

    public boolean isCorrect() {
        return n % 2 == 0;
    }
}
Run Code Online (Sandbox Code Playgroud)

该类在我的代码中初始化,我通常无法访问测试中的那部分代码.
在我的一些测试中,我想模拟它,以便如果类的值初始化为3,'isCorrect'将返回true(这不是正常的行为),并且在其他一些测试中我想要模拟它以便无论如何初始化,'isCorrect'都将返回false.

我试图在文档中找到一种方法,但它不是那么用户友好,我放弃了它.

ass*_*ias 5

对于您的第一种情况,您可以:

new MockUp<A> () {
     private int n;
     @Mock public void $init(int n) { this.n = n; }
     @Mock public boolean isCorrect() { return n == 3; }
};
Run Code Online (Sandbox Code Playgroud)

而对于你的第二个例子:

new MockUp<A> () {
     @Mock public boolean isCorrect() { return false; }
};
Run Code Online (Sandbox Code Playgroud)

例如,这会打印false,true,false,false:

new MockUp<A> () {
     private int n;
     @Mock public void $init(int n) { this.n = n; }
     @Mock public boolean isCorrect() { return n == 3; }
};
System.out.println(new A(2).isCorrect());
System.out.println(new A(3).isCorrect());

new MockUp<A> () {
     @Mock public boolean isCorrect() { return false; }
};
System.out.println(new A(2).isCorrect());
System.out.println(new A(3).isCorrect());
Run Code Online (Sandbox Code Playgroud)

编辑

在您的评论之后,仅对n的某些值模拟类的一种方法是使用反射来检查字段的值:

new MockUp<A> () {
     @Mock public boolean isCorrect(Invocation invocation) {
        // Gets the invoked instance.
        A a = invocation.getInvokedInstance();
        int n = Deencapsulation.getField(a, "n");
        if (n == 3) return true;
        else return a.isCorrect();
     }
};
Run Code Online (Sandbox Code Playgroud)

但它变得有点脆弱,因为它取决于你的类A中变量的名称.

一个更好的替代方案是在A类中为测试目的提供一个受包保护的getter int getN() { return n; },你不再需要反射了.