繁体   English   中英

在静态方法中使用Powermock和Mockito模拟本地范围对象

[英]Mocking Local Scope Objects using Powermock and mockito within a static method

这个问题可能已经被问过很多次了。 但是,我在任何地方都找不到答案。 我在这里处理遗留代码。

请注意:我正在简化我的问题以获得非常具体的答案。 代码段仅代表我面临的问题。 不是我要测试的实际代码。 这里要测试的代码片段代表了我需要测试的全部代码的一部分。

问题:实际上正在调用myObj.loadContent(null,null),而不是像PowerMockito.doNothing()。when(mockObj).loadContent(null,null)所指定的那样不执行任何操作;

我想进行单元测试的代码:

class ClassInstantiatingObject {
.
.
    public static void doSomething(Arg1 arg1, Arg2 arg2) throws Exception{
        MyClass myObj = new MyClass(arg1, arg2);
        myObj.loadContent(null, null);
    }
}

我的单元测试:

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
.
.
.
@Test
public void testDoSomething() throws Exception {
    MyClass mockObj = PowerMockito.mock(MyClass.class);
    PowerMockito.whenNew(MyClass.class).withAnyArguments().thenReturn(mockObj);
    PowerMockito.doNothing().when(mockObj).loadContent(null, null);
    Arg1 mockArg1 = mock(Arg1.class);
    Arg2 mockArg2 = mock(Arg2.class);
    StaticClass.doSomething(mockArg1, mockArg2);
}

要测试的代码无法更改。 因此,我需要一种不使用Mockito / Powermock实际调用loadContent(null,null)的方法。

另外,在使用时:PowerMockito.doNothing()。when(MyClass.class,“ loadContent”,null,null)或PowerMockito.doNothing()。when(MyClass.class,“ loadContent”,Mockito.anyString(),Mockito。 anyMap())

我在org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.addAnswersForStubbing中获得了java.lang.NullPointerException

正确答案

我设法找出解决方案。 老实说很简单。

在上面指定的示例中。 我缺少的是,在使用PowerMockito.whenNew()的情况下,必须在批注@PrepareForTest中指定正在调用您要模拟的构造函数的类。 根本不需要指定要模拟其构造函数的类。

例如。

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)

//Only need to declare the class calling the constructor to use 
//PowerMockito.whenNew(). You do not need to declare the class whose mock 
//you plan on returning in case of the constructor call.
//In this case, no need to mention MyClass.class in PrepareForTest

@PrepareForTest({ClassInstantiatingObject.class})
public class ClassInstantiatingObjectTest
{
.
.
.
    @Test
    public void testDoSomething() throws Exception {
        MyClass mockObj = PowerMockito.mock(MyClass.class);
        PowerMockito.whenNew(MyClass.class).withAnyArguments().thenReturn(mockObj);

        //Only way to do nothing via Powermock for a local scope object
        //whose method call returns void

        //PowerMockito.doNothing().when(mockObj.loadContent(null,null)); 
        //will cause a compile time exception

        PowerMockito.doNothing().when(mockObj,"loadContent",null,null);
        Arg1 mockArg1 = mock(Arg1.class);
        Arg2 mockArg2 = mock(Arg2.class);
        StaticClass.doSomething(mockArg1, mockArg2);
    }
}

上面的代码将是解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM