我想测试一个使用它的参数化构造函数创建另一个类的对象的方法。即使我嘲笑了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()
最终调用thridPartyLib.someMethod(profile);
,它是MyClass构造函数的一部分。
@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();
}
}
答案 0 :(得分:2)
只有在使用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();
}
}
答案 1 :(得分:0)
疼痛可能暗示另一种方法。考虑将工厂注入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()
是否按预期调用。