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

Java JMockit:如何根据构造函数中给定的参数模拟方法?,java,mocking,jmockit,Java,Mocking,Jmockit,我想使用JMockit模拟以下类: 公共A类{ 私人int n; 公共A(国际n){ 这个,n=n; } 公共布尔值isCorrect(){ 返回n%2==0; } } 该类在我的整个代码中都是初始化的,在测试中我通常无法访问该部分代码。 在我的一些测试中,我想模拟它,这样如果用值3初始化该类,“isCorrect”将返回true(这不是正常的行为),而在其他一些测试中,我想模拟它,这样无论如何初始化,“isCorrect”都将返回false 我试图在文档中找到一种方法来实现这一点,但它不是那

我想使用JMockit模拟以下类:

公共A类{
私人int n;
公共A(国际n){
这个,n=n;
}
公共布尔值isCorrect(){
返回n%2==0;
}
}
该类在我的整个代码中都是初始化的,在测试中我通常无法访问该部分代码。
在我的一些测试中,我想模拟它,这样如果用值3初始化该类,“isCorrect”将返回true(这不是正常的行为),而在其他一些测试中,我想模拟它,这样无论如何初始化,“isCorrect”都将返回false


我试图在文档中找到一种方法来实现这一点,但它不是那么友好,因此我放弃了它。

对于您的第一个案例,您可以:

new MockUp<A> () {
     private int n;
     @Mock public void $init(int n) { this.n = n; }
     @Mock public boolean isCorrect() { return n == 3; }
};
新模型(){
私人int n;
@Mock public void$init(int n){this.n=n;}
@模拟公共布尔值isCorrect(){return n==3;}
};
第二个例子是:

new MockUp<A> () {
     @Mock public boolean isCorrect() { return false; }
};
新模型(){
@模拟公共布尔值isCorrect(){return false;}
};
例如,这将打印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());
新模型(){
私人int n;
@Mock public void$init(int n){this.n=n;}
@模拟公共布尔值isCorrect(){return n==3;}
};
System.out.println(新的A(2.isCorrect());
System.out.println(新的A(3.isCorrect());
新模型(){
@模拟公共布尔值isCorrect(){return false;}
};
System.out.println(新的A(2.isCorrect());
System.out.println(新的A(3.isCorrect());

编辑

在您的注释之后,仅针对特定的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();
     }
};
新模型(){
@模拟公共布尔值isCorrect(调用调用){
//获取被调用的实例。
A=invocation.getInvokedInstance();
int n=deincapsulation.getField(a,“n”);
如果(n==3)返回true;
否则返回a.isCorrect();
}
};
但它变得有点脆弱,因为它取决于类a中变量的名称


一个更好的选择是在类A中为测试目的提供一个包保护的getter:
int getN(){return n;}
并且您不再需要反射。

谢谢@assylias的回答。我想我找到了一个更好的方法来实现第一个mock,它结合了第一个和第二个(编辑后)答案中的想法。事情是这样的:

新模型(){
私人int n;
@嘲弄
公共void$init(调用inv,int n){
这个,n=n;
继续投资();
}
@嘲弄
公共布尔值isCorrect(调用inv){
如果(n==3){
返回true;
}
返回库存继续();
}
};
更新

对于第二个模拟(brute false return),将执行以下操作:

新模型(){
@嘲弄
公共布尔值isCorrect(){
返回false;
}
};

再次感谢@assylias在这方面的帮助:)

您的第二个示例(始终返回false)效果很好,但不是第一个。我希望mock类在3中返回true,但在所有其他情况下都能正常运行(无需在mock中重新编写原始逻辑),我也不想忽略原始构造函数正在做的事情(最多只向其添加逻辑)。我添加了一个答案,在我看来这是一个更好的解决方案。我注意到,用户一直在对这个答案投票,但没有任何解释。这仍然是IMHO更可取的方式,因为@assylias answer依赖于字段名,而这个则不依赖于字段名(他/她甚至写
,但它变得有点脆弱,因为它依赖于类a中变量的名称)。有人能想出为什么这是一个不太可取的答案吗?