Java 模拟不应用于新对象创建
我试图模拟一个新的对象创建Java 模拟不应用于新对象创建,java,junit,mockito,Java,Junit,Mockito,我试图模拟一个新的对象创建 公共类MyServiceTest{ MyClass MyClass; myClass=Mockito.mock(myClass.class); Mockito.when(新建MyClass()).thenReturn(MyClass); } 错误: org.mockito.exceptions.misusing.MissingMethodInvocationException: when()需要的参数必须是“模拟的方法调用”。 例如: when(mock.getAr
公共类MyServiceTest{
MyClass MyClass;
myClass=Mockito.mock(myClass.class);
Mockito.when(新建MyClass()).thenReturn(MyClass);
}
错误:
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when()需要的参数必须是“模拟的方法调用”。
例如:
when(mock.getArticles())。然后返回(articles);
此外,出现此错误的原因可能是:
1.您可以存根:final/private/equals()/hashCode()方法。
这些方法无法存根/验证。
不支持对非公共父类声明的模拟方法。
2.在when()中,您不在mock上调用方法,而是在其他对象上调用方法
我确实模拟了myClass对象,但它在方法调用时被分配给了一个新对象:
公共类MyService{
公共静态字符串myMethod(){
MyClass MyClass=新的MyClass();
//..........
}
}
这是正确的行为;Mockito不支持模拟新对象创建。您需要另一个类似的库,或者需要重构测试
要进一步了解基于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
创建模拟对象。请注意,您并没有对MyObject的所有实例设置期望值;相反,您正在创建一个要控制的实例。在内部,这实际上是MyObject的一个一次性子类,其所有方法都被覆盖,因此Mockito只适用于可见的非最终实例方法(您可以自己覆盖)。当
时,唯一可以进入内部的是对Mockito创建的mock上的方法的单个调用,因此您的新的
关键字在这里不起作用
new
,所以通常需要将模拟插入到测试系统中。你(几乎)从不嘲笑被测试的系统;你是在嘲笑合作者,因为你不能使用new
,所以你通常必须把它传进来。这是我的一部分assertEquals
,使用Mockito创建的mock调用verify
,或者两者的某种组合请记住,仅使用Mockito,在调用
new
时,您将无法让Java返回一个mock,因此您需要像上面的步骤3那样的步骤。或者,是EasyMock或Mockito之上的扩展库,它具有静态方法,如whenNew
和mockStatic
,用于更高级的模拟。(不过需要注意的是:由于PowerMock使用一种特殊的类加载器来重写类,因此设置起来可能会更困难,而且它的魔力可能会使您的测试更难推理。重构可能是让您的测试更容易理解的一种方法。)首先:我建议不要使用PowerMock。因为使用此框架通常会导致奇怪的错误,而且:您必须了解,您没有面临Mockito的“缺陷”。。。但你的设计有缺陷
基本上,您希望了解如何使用。整个想法是:在生产代码中不调用new。因为,你不能假装叫“新”。相反,您推送生产代码所需的对象。。。进入你的课堂
对于正常(生产)工作,推送正常对象;对于单元测试,您可以推入模拟对象
换句话说:如果您认为您的设计需要测试PowerMock;然后,这会告诉您需要重新设计。您可以尝试powermock。这对我有用
import org.powermock.api.mockito.PowerMockito;
MyClass myClassMock = Mockito.spy(new MyClass());
PowerMockito.whenNew(MyClass.class).withNoArguments().thenReturn(myClassMock);
公共类MyServiceTest{
MyClass MyClass;
myClass=PowerMockito.mock(myClass.class);
whenNew(MyClass.class),然后return(MyClass);
}
添加了powermock并进行了尝试<代码>MyClass MyClass;myClass=Mockito.mock(myClass.class);whenNew(MyClass.class).withNoArguments()。然后返回(MyClass)但是仍然只在MyService.myMethod()
中获取新对象,这就是我;但我永远不会向任何人推荐PowerMock;尤其是新手。相反,我们应该向人们解释如何进行正确的设计(和DI)。@Jägermeister的人对于PowerMockito是否值得一提非常固执己见。在PowerMock中,答案以100%以上的优势战胜了被接受的答案。类似地,我以前也曾试图对PowerMock的字节码操作提出过严厉警告,但它确实存在。只需说重构是更好的答案,但忽略PowerMock无论如何都是不完整的,否则很可能在没有解释或警告的情况下添加它。@ep您已经发现了我描述的更困难的设置;那里的陷阱值得他们提出自己的问题,并且不适合这个评论框,但正如前面提到的,重构代码无论如何都是更好的解决方案;试试这个!这对我有用。建议:不要尝试在方法中使用new运算符创建对象,因为spring Framework不建议这样做您的代码不会编译