Mock不会应用于新对象的创建



我试图模拟一个新的对象创建

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();
  1. mock创建一个mock对象。请注意,您并没有对MyObject的所有实例设置期望值;相反,您要创建一个要控制的实例。在内部,这实际上是MyObject的一个一次性子类,其所有方法都被覆盖,因此Mockito只适用于可见的非最终实例方法(您可以自己覆盖)。

  2. 您可以使用when调用存根行为。唯一可以进入when的是对Mockito创建的mock上的方法的单个调用,因此new关键字在这里不起作用。

  3. 同样,因为不能使用new,所以通常需要将mock插入到测试中的系统中。你(几乎)从不嘲笑测试中的系统;你在嘲笑合作者,因为你不能使用new,所以你通常必须把它传进来。这就是Mockito在依赖注入系统中工作得如此好的部分原因。

  4. 然后调用测试中的方法。。。

  5. 。。。并检查最终状态是否为您想要的状态。这可以是来自测试框架的断言,如assertEquals,使用Mockito创建的mock调用verify,或者两者的某种组合。

请记住,只有Mockito,Java在调用new时将无法返回mock,因此您需要类似上面步骤3的步骤。或者,PowerMock是EasyMock或Mockito之上的一个扩展库,它具有whenNewmockStatic等静态方法,用于更高级的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);
}

相关内容

  • 没有找到相关文章

最新更新