我正在尝试为遗留代码编写测试。我要测试的其中一个类是构造函数。这个构造函数本身调用了其他几种方法。
我正在尝试为此构造函数编写单元测试,以验证构造函数调用的方法是否确实已被调用。
我在eclipse Luna Release(4.4.0)上使用PowerMock 1.5.5和Mockito 1.9.5与测试NG和eclipse(org.testng.eclipse - 6.8.6.20141201_2240)。
我可以请求指导我做错了吗? 我得到了例外:
想要但未被调用:classWithConstructor.doSomethingWithS(); - > at com.example.constructortester.MakerOfClassWithConstructorTest.testSomething(MakerOfClassWithConstructorTest.java:30) 实际上,这个模拟没有互动。
我期望doSomethingWithS应该被调用,但是我得到的错误消息告诉我Mock本身没有被使用,因此我期望在spy上调用的方法永远不会被调用。
以下是代码段:
具有构造函数的遗留类,后者又调用另一种方法
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;
}
}
我用作构建器的课程:
package com.example.constructortester;
public class MakerOfClassWithConstructor {
public MakerOfClassWithConstructor() {
}
public void doSomething(String s) {
new ClassWithConstructor(s);
}
}
最后,TestNG测试:
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);
}
}
答案 0 :(得分:2)
这是一个Java错误。
尝试在测试启动器的VM参数中添加-noverify
。
或者(最好的解决方案)更新JDK。我的版本是1.7.0_u67,我将其更新为版本1.7.0_u79并且工作正常(即使没有-noverify
)。
答案 1 :(得分:0)
您必须在验证之前使用模拟对象调用该方法 所以你应该添加一行
spyClassWithConstructor.doSomethingWithS(someOtherString);
之前
Mockito.verify(spyClassWithConstructor, times(1)).doSomethingWithS(
someOtherString);
在你的情况下它不会验证(跳过它),因为你甚至没有调用方法,只有在调用方法后才能进行验证