Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 模拟不应用于新对象创建_Java_Junit_Mockito - Fatal编程技术网

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不建议这样做您的代码不会编译