我想测试一种使用其参数化构造函数创建另一个类的对象的方法。即使我嘲笑了MyClass的构造函数,它也使第三方库在构造函数实现中并导致错误。我正在使用Mockito/PowerMockito。
public class MyClass{
private MyObj obj;
MyClass (String profile)
{
//some 3rd party library call
obj = thridPartyLib.someMethod(profile);
}
public String someMethod(){
return obj.someExternalCall();
}
}
我想测试的课程
public class ClassTobeTested{
public void execute(){
//some code
// ......
MyClass myClass = new MyClass(profile);
myclass.someMethod();
}
}
我到目前为止尝试过的 - classUnderTest.execute()
最终调用了MyClass构造函数的thridPartyLib.someMethod(profile);
。
@RunWith(PowerMockRunner.class)
@PrepareForTest(MyClass.class)
public class ClassTobeTestedTest {
private MyClass mockMyClass;
private ClassTobeTested classUnderTest;
@Before
public void init() {
classUnderTest = new ClassTobeTested();
mockMyClass = PowerMockito.mock(MyClass.class);
}
@Test
public void testExecute(){
PowerMockito.whenNew(MyClass.class)
.withArguments(Mockito.any())
.thenReturn(mockMyClass);
classUnderTest.execute();
}
}
您的代码仅在使用classundertest的间谍或模拟时才能工作。尝试这个。这应该有效
@RunWith(PowerMockRunner.class)
@PrepareForTest( {MyClass.class, ClassTobeTested.class })
public class ClassTobeTestedTest {
private MyClass mockMyClass;
private ClassTobeTested classUnderTest;
@Before
public void init() {
classUnderTest = spy(new ClassTobeTested());
mockMyClass = PowerMockito.mock(MyClass.class);
}
@Test
public void testExecute() throws Exception {
PowerMockito.whenNew(MyClass.class)
.withArguments(Mockito.any())
.thenReturn(mockMyClass);
classUnderTest.execute();
}
}
疼痛可能暗示另一种方法。考虑将工厂注入ClassTobeTested
中,该工厂知道如何创建MyObj
实例。例如:
class MyObjFactory {
MyObj create(String profile) {
return new MyClass(profile);
}
}
然后
public class ClassTobeTested {
private final MyObjFactory factory;
public ClassTobeTested(MyObjFactory factory) {
this.factory = factory;
}
public void execute(){
//some code
// ......
// MyClass myClass = new MyClass(profile);
MyClass myClass = factory.create(profile);
myclass.someMethod();
}
}
因此,单位测试变得更简单,只需模拟工厂并返回模拟的MyClass
实例即可。然后,验证 myclass.someMethod()
的调用很简单。