Reputation: 11
I am trying to write tests for legacy code. One of the classes I am trying to test is a constructor. This constructor itself invokes several other methods.
I am trying to write a unit test for this constructor to verify that the methods invoked by the constructor are indeed invoked.
I am using PowerMock 1.5.5 and Mockito 1.9.5 with Test NG with eclipse (org.testng.eclipse - 6.8.6.20141201_2240) on eclipse Luna Release (4.4.0).
Could I please ask for guidance on what I am doing wrong? I get the exception:
Wanted but not invoked: classWithConstructor.doSomethingWithS(); -> at com.example.constructortester.MakerOfClassWithConstructorTest.testSomething(MakerOfClassWithConstructorTest.java:30) Actually, there were zero interactions with this mock.
I expected that doSomethingWithS should have been invoked, but the error message I get tells me that the Mock itself is not used, and therefore the method I expected to be invoked on the spy can never be invoked.
Below are the code snippets:
The legacy class that has the constructor, which in turns calls another method
package com.example.constructortester;
public class ClassWithConstructor {
public static final String MODIFIED = "Modified:";
public ClassWithConstructor(String s) {
String returnVal = doSomethingWithS(s);
System.out.println("ClassWithConstructor::ClassWithConstructor - :"
+ returnVal);
}
protected String doSomethingWithS(String s) {
System.out
.println("ClassWithConstructor::doSomethingWithS - Something with s:"
+ s);
return MODIFIED + s;
}
}
My class that I use as a builder:
package com.example.constructortester;
public class MakerOfClassWithConstructor {
public MakerOfClassWithConstructor() {
}
public void doSomething(String s) {
new ClassWithConstructor(s);
}
}
Finally, the TestNG test:
package com.example.constructortester;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertEquals;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.testng.PowerMockTestCase;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@PrepareForTest(MakerOfClassWithConstructor.class)
public class MakerOfClassWithConstructorTest extends PowerMockTestCase {
@Test
public void testSomething() throws Exception {
final String someString = "Test";
final String someOtherString = "SomeOtherTest";
ClassWithConstructor spyClassWithConstructor = spy(new ClassWithConstructor(
someString));
PowerMockito.whenNew(ClassWithConstructor.class)
.withArguments(someString).thenReturn(spyClassWithConstructor);
PowerMockito.doReturn(someOtherString).when(spyClassWithConstructor)
.doSomethingWithS(someString);
// PowerMockito.when(spyClassWithConstructor.doSomethingWithS(someString))
// .thenReturn(someOtherString);
new MakerOfClassWithConstructor().doSomething(someString);
// This works
PowerMockito.verifyNew(ClassWithConstructor.class).withArguments(
someString);
// This fails with error:
// Wanted but not invoked:
// classWithConstructor.doSomethingWithS(<any>);
// -> at
// com.example.constructortester.MakerOfClassWithConstructorTest.testSomething(MakerOfClassWithConstructorTest.java:30)
// Actually, there were zero interactions with this mock.
Mockito.verify(spyClassWithConstructor, times(1)).doSomethingWithS(
someOtherString);
}
}
Upvotes: 1
Views: 2799
Reputation: 121
This is a Java bug.
Try to add -noverify
in the VM arguments of the test launcher.
Or (the best solution) update the JDK. Mine was 1.7.0_u67 and I updated it to version 1.7.0_u79 and worked (even without the -noverify
).
Upvotes: 2
Reputation: 1482
you have to call the method using the mock object before verifying it so you should add a line
spyClassWithConstructor.doSomethingWithS(someOtherString);
before
Mockito.verify(spyClassWithConstructor, times(1)).doSomethingWithS(
someOtherString);
In your case it is not going to verify(skipping it) because you have not even called the method, Verification can be done only after you call the method
Upvotes: 0