The questions Debug Partial Mock in JMockit and Debugging Java code tested with Spock and JMockit already deal with the issue, that breakpoints in your software under test (SUT) get ignored when the class gets redefined/instrumented by JMockit. The recommended solution is that you should add an additional breakpoint in your testclass in order to re-activate the breakpoints in SUT, once the execution stops in your testclass.
However, this solution does not work, if you are using the @Tested
annotation in your testclass, because in this case the breakpoint in the testclass itself gets ignored.
Here is an example:
package de.playground;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import mockit.Expectations;
import mockit.Injectable;
import mockit.integration.junit4.JMockit;
@RunWith(JMockit.class)
public class DebuggingWithJMockitTest {
public interface Collaborator {
String execute(String... args);
}
public static class ToTest {
private Collaborator collaborator;
public ToTest(Collaborator collaborator) {
this.collaborator = collaborator;
}
public String doSomething() {
return collaborator.execute("a", "b");
}
}
@Injectable
private Collaborator collaborator;
@Tested
private ToTest toTest;
@Test
public void testHoldOnBreakpoint() {
new Expectations() {{
collaborator.execute((String[]) any); result = "whatever";
}};
String result = toTest.doSomething(); // add breakpoint here
assertThat(result, is("whatever"));
}
}
In this case the debugger does not stop in the String result = toTest.doSomething();
line. If you do not use the @Tested
annotation and initialize the SUT in a @Before
method like this:
// @Tested is not used
private ToTest toTest;
@Before
public void before() {
toTest = new ToTest(collaborator);
}
the breakpoint works perfectly fine.
Is there any workaround how you can debug your code even if you are using the @Tested
annotation in the test class?