如何在Junit中模拟子类的构造函数?
问题描述:
类结构看下面喜欢:如何在Junit中模拟子类的构造函数?
class A {
protected String a;
protected String b;
A(String b1) {
new A("A111", b1);
}
A(String a1, String b1) {
a = a1;
b = b1;
}
}
class B extends A {
B(String b) {
super("A", b);
}
}
我需要编写JUnit测试案例,需要嘲笑构造为A类,以便每当对象为B类需要创建A类,然后模拟构造应该得到调用和从模拟构造函数返回对象。
我尝试以下操作:
new MockUp<A>() {
@Mock
public void $init(String b1) {
new A("A11111111", b1);
}
};
但在嘲笑构造函数创建的对象没有得到回报。
答
好吧,你是在正确的道路上......它需要的@Mock
,MockUp
,Invocation
和Deencapsulation
组合......你要添加一个Invocation
您$init
模拟方法,然后用Deencapsulation闲逛在A
内部。这是一个例子。我使用了你的A和B类,只是将它们清理一些,并添加getters以便于使用。我故意没有添加setter,所以我可以炫耀如何解决缺乏setter的问题。
package com.example.dcsohl;
import org.junit.Test;
import mockit.Deencapsulation;
import mockit.Invocation;
import mockit.Mock;
import mockit.MockUp;
public class TestTest {
public static class A {
protected String a;
protected String b;
public A(String b1) {
this("A111", b1);
}
public A(String a1, String b1) {
a = a1;
b = b1;
}
}
public static class B extends A {
public B(String b1) {
super("A", b1);
}
public String getA() {
return this.a;
}
public String getB(){
return this.b;
}
}
@Test
public void test() {
new MockUp<A>() {
@Mock public void $init(Invocation inv, String a1, String b1) {
A a = inv.getInvokedInstance();
Deencapsulation.setField(a, "b", b1);
}
};
B b = new B("foo");
System.out.println(b.getA());
System.out.println(b.getB());
}
}
你会注意到,在年底,打印证明我成功设置的b
的价值,但是,不舍a
独自一人,它出来作为null
。
+0
感谢您的建议并提供解决方案。它工作顺利! – Abhishek
我不明白你的要求。你能解释一下你想做什么以及想要测试什么吗? – Tunaki
看起来好像你想将超类构造函数从子类中分离出来,并且只测试子类的逻辑(通过模仿超类)?但事情是这样的:构造函数不会真的返回对象 - 当你调用super()时,你不会将它分配给任何东西,因为它在'this'上运行......所以你不能“调用并返回对象从模拟构造函数“在这种情况下。 – dcsohl
我想模拟单参数化构造函数和模拟构造函数,我想创建使用两个参数化构造函数的对象,并返回相同的对象供进一步使用。 – Abhishek