【问题标题】:Powermock not intercepting new object creationPowermock 不拦截新对象的创建
【发布时间】:2015-01-25 01:58:17
【问题描述】:

我正在尝试测试一个方法,该方法创建另一个我希望使用 powermock 模拟的类的新实例。我的代码(简化)如下-

测试代码:

import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import static org.easymock.EasyMock.anyObject;
import static org.powermock.api.easymock.PowerMock.*;

@RunWith(PowerMockRunner.class)
@PrepareForTest( { ClassUnderTest.class } )
public class TestForClassUnderTest {

    private ClassToBeMocked classToBeMocked;
    private ClassUnderTest classUnderTest;

    public void testSimple() throws Exception {

        classToBeMocked = createMock(ClassToBeMocked.class);
        // trying to intercept the constructor
        // I *think* this is the root cause of the issue 
        expectNew(ClassToBeMocked.class, anyObject(), anyObject(), anyObject()).andReturn(classToBeMocked);

        classToBeMocked.close();
        expectLastCall();
        replayAll();

        // call to perform the test
        classUnderTest.doStuff();
    }
} 

正在测试的代码:

import ClassToBeMocked;

public class ClassUnderTest {
    private ClassToBeMocked classToBeMocked;

    public void doStuff() {

        classToBeMocked = new ClassToBeMocked("A","B","C");
        // doing lots of other things here that I feel are irrelevant
        classToBeMocked.close();
    }
}

我想模拟的代码:

public class ClassToBeMocked {
    public ClassToBeMocked(String A, String B, String C) {
    // irrelevant
    }
    public close() {
    // irrelevant
    }
}

我得到的错误如下:

java.lang.ExceptionInInitializerError

    at ....more inner details of where this goes into

    at ClassToBeMocked.close

    at ClassUnderTest.doStuff

    at TestForClassUnderTest.test.unit.testSimple

Caused by: java.lang.NullPointerException

PowerMock 版本:1.4.5

EasyMock 版本:3.1

PS:我已将代码精简到最低限度,仅显示模拟库的详细信息,如果您认为我的其他代码有某种干扰,请告诉我,我可以提供有关您认为重要的位的更多详细信息显示。任何指向这样做的其他示例的链接甚至可能会有所帮助。

【问题讨论】:

    标签: java unit-testing testing powermock easymock


    【解决方案1】:

    我意识到这不起作用的原因是我正在扩展另一个类。我有

    @RunWith(PowerMockRunner.class)
    @PrepareForTest( { ClassUnderTest.class } )
    public class TestForClassUnderTest extends AnotherClass {
    
    }
    

    只要我删除了扩展,它就起作用了。不确定它是否无法使用 powermock 扩展另一个类或由于另一个类,但删除它对我有用

    【讨论】:

      【解决方案2】:

      当你想模拟任何类的新实例时,你应该这样做

      Powermock.expectNew(ClassYouWishToMock.class).andReturn(whateverYouWantToReturn).anyTimes();
      Powermock.replayAll();
      

      当在此类上调用 new 时,这将返回 'whateverYouWantToReturn'。

      但是当你想模拟一个实例变量时,你应该使用easymock的Whitebox特性。

      看看下面的例子

      Class A{
           private B b;
      }
      

      为了模拟这个,我的测试类看起来像这样

      ...//other powermock, easymock class level annotations
      @PrepareForTest(B.class)
      class ATest{
              Whitebox.setInternalState(B.class,b,whateverValueYouWantYourMockedObjectToReflect);
      }
      

      这里'b'传入参数,是你要模拟的变量名。

      祝你好运!

      【讨论】:

      • 这有点类似于我所做的,不是吗?我只是没有 .anyTimes() ?
      • 你的变量是实例变量吗?我应该早点看到的
      • 对不起哪个变量?你能指定名字吗?
      • 在您正在测试的实际代码中,ClassToBeMocked 的对象是否定义为实例变量?
      • 所以在我要测试的代码中,每次运行测试代码时,我都会创建一个新的 ClassToBeMocked 实例,如上所示 - "classToBeMocked = new ClassToBeMocked("A","B"," C");"
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多