I am currently attempting to test the execution path of my code, but I ran into some issues when it came to nested class member variables. Consider the following class structure:
System (System under test)
-> ClassA
-> ClassB
-> ClassC
A class named System
contains an instance of ClassA
, and will invoke one of its methods. ClassA
will similarly contain an instance of ClassB
and will invoke one of it's methods, etc.
@RunWith(JMockit.class)
public class SomeTest {
@Tested
private System system;
@Injectable
private ClassA memberA;
@Injectable
private ClassB memberB;
@Injectable
private ClassC memberC;
@Test
public void doSystemTest() {
// Do stuff
system.handle();
new Verifications() {
{
system.handle(); times = 1;
memberA.doSomeAStuff(); times = 1;
memberB.doSomeBStuff(); times = 1; // Results in test failure:
}
};
}
}
When I run this test, I get the following error:
Missing 1 invocation to: ca.kgli.jmockit.ClassB#doSomeBStuff() on mock instance: ca.kgli.jmockit.ClassB@1a052a00
For reference, here is the code:
public class System {
private ClassA memberA;
public void handle() {
memberA.doSomeAStuff();
}
}
public class ClassA {
private ClassB memberB;
public void doSomeAStuff() {
memberB.doSomeBStuff();
}
}
public class ClassB {
private ClassC member;
public void doSomeBStuff() {
member.stuffCSays("arsenic");
}
}
public class ClassC {
public String stuffCSays(String input) {
return "Hello, " + input;
}
}
So my question is, why is the method doSomeBStuff
not being invoked? Was JMockit not meant to be used in this way? I'm new to this test toolkit so any help or insight into this problem would be greatly appreciated.
When you mock ClassA
, the real implemention of doSomeAStuff()
is intercepted by Jmockit, so it will not call doSomeBStuff()
.
You should only mock ClassA
when you perform unit test on System
.
@RunWith(JMockit.class)
public class SomeTest {
@Tested
private System1 system;
@Injectable
private ClassA memberA;
@Test
public void doSystemTest() {
// Do stuff
system.handle();
new Verifications() {
{
memberA.doSomeAStuff(); times = 1;
}
};
}
}
The mock of ClassB
should only occur when you perform unit test on ClassA
.