Classes structures look likes below:
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);
}
}
I need to write JUnit test case and needs to mock constructor for class A so that whenever object for class B needs to create then mock constructor for class A should get invoke and returns object from mock constructor.
I tried following :
new MockUp<A>() {
@Mock
public void $init(String b1) {
new A("A11111111", b1);
}
};
But object created in mocked constructor hasn't been returned.
Ok, you were on the right path ... it takes a combination of @Mock
, MockUp
, Invocation
and Deencapsulation
... You have to add an Invocation
to your $init
mock method, and then use Deencapsulation to poke around at A
internals. Here's an example. I used your A and B classes, only cleaning them up a little bit and adding getters for ease-of-use. I deliberately did not add setters, so I could show off how to get around a lack of setters.
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());
}
}
You'll note that, at the end, the printouts show that I successfully set the value of b
but, having left a
alone, it comes out as null
.