我试图模拟一个新的对象创建
public class MyServiceTest {
MyClass myClass;
myClass = Mockito.mock(MyClass.class);
Mockito.when(new MyClass()).thenReturn(myClass);
}
错误:
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
此外,出现此错误可能是因为:1.您可以截尾以下任一方法:final/private/equals()/hashCode()。不能对的那些方法进行存根处理/验证。不支持在非公共父类上声明的模拟方法。2.在when()内部,您不在mock上调用方法,而是在其他对象上调用方法。
我确实模拟了myClass对象,但它在方法调用时被分配给了一个新对象:
public class MyService {
public static String myMethod(){
MyClass myClass = new MyClass();
//..........
}
}
首先:我建议不要使用PowerMock。由于使用这个框架经常会导致奇怪的错误,并且:你必须明白,你没有面临Mockito的"缺陷"。。。但你的设计有缺陷。
基本上,您希望了解如何使用依赖项注入。整个想法是:您不会在生产代码中调用new。因为,你不能嘲笑称之为"新"。相反,您推送生产代码所需的对象。。。进入你的课堂。
对于正常(生产)工作,推送正常对象;对于单元测试,您可以推入模拟对象。
换句话说:如果你认为你的设计需要测试PowerMock;然后告诉你的设计需要重新设计。
这是正确的行为;Mockito不支持模拟新对象的创建你需要另一个像PowerMock这样的库,或者你需要重构你的测试。
要了解更多关于基于Mockito的测试的每个部分的信息:
/* 1 */ MyObject myObjectMock = Mockito.mock(MyObject.class);
/* 2 */ when(myObjectMock.methodCall()).thenReturn("return value");
/* 3 */ MySystemUnderTest systemUnderTest = new MySystemUnderTest(myObjectMock);
/* 4 */ systemUnderTest.methodToTest();
/* 5 */ verify(myObjectMock).methodCalledByTheSystemUnderTest();
mock
创建一个mock对象。请注意,您并没有对MyObject的所有实例设置期望值;相反,您要创建一个要控制的实例。在内部,这实际上是MyObject的一个一次性子类,其所有方法都被覆盖,因此Mockito只适用于可见的非最终实例方法(您可以自己覆盖)。您可以使用
when
调用存根行为。唯一可以进入when
的是对Mockito创建的mock上的方法的单个调用,因此new
关键字在这里不起作用。同样,因为不能使用
new
,所以通常需要将mock插入到测试中的系统中。你(几乎)从不嘲笑测试中的系统;你在嘲笑合作者,因为你不能使用new
,所以你通常必须把它传进来。这就是Mockito在依赖注入系统中工作得如此好的部分原因。然后调用测试中的方法。。。
。。。并检查最终状态是否为您想要的状态。这可以是来自测试框架的断言,如
assertEquals
,使用Mockito创建的mock调用verify
,或者两者的某种组合。
请记住,只有Mockito,Java在调用new
时将无法返回mock,因此您需要类似上面步骤3的步骤。或者,PowerMock是EasyMock或Mockito之上的一个扩展库,它具有whenNew
和mockStatic
等静态方法,用于更高级的mocking。(不过需要注意的是:因为PowerMock使用了一个特殊的类加载器来重写你的类,所以它可能更难设置,而且它的魔力可能会让你的测试更难推理。重构可能是让测试更容易理解的更好方法。)
您可以尝试powermock。它对我有效。
import org.powermock.api.mockito.PowerMockito;
MyClass myClassMock = Mockito.spy(new MyClass());
PowerMockito.whenNew(MyClass.class).withNoArguments().thenReturn(myClassMock);
public class MyServiceTest {
MyClass myClass;
myClass = PowerMockito.mock(MyClass.class);
PowerMockito.whenNew(MyClass.class).thenReturn(myClass);
}