【问题标题】:Powermockito whenNew returns null if not matched如果不匹配,Powermockito whenNew 返回 null
【发布时间】:2018-12-12 11:09:32
【问题描述】:

我不知道它是否应该这样做,但我想不是。看看我下面的代码。

File mocked = PowerMockito.mock(File.class);    
PowerMockito.whenNew(File.class).withParameterTypes(String.class).withArguments(eq(THE_TARGET_PATH)).thenReturn(mocked);
File normalFile = new File(WORKING_PATH);
File mockedFile = new File(THE_TARGET_PATH);

我确实希望normalFile 会正常创建,但它实际上是null。顺便说一句,mockedFile 被正确模拟了。

我也在使用@RunWith(PowerMockRunner.class)@PrepareForTest({ClassWhereInstanceIsCreated.class, File.class})

我正在使用:

<dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-module-junit4</artifactId>
        <version>1.7.4</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-api-mockito</artifactId>
        <version>1.7.4</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-core</artifactId>
        <version>1.7.4</version>
        <scope>test</scope>
    </dependency>

【问题讨论】:

    标签: java testing mockito powermock


    【解决方案1】:

    我的发现表明,使用 PowerMockito / PowerMockito 2 进行部分构造函数模拟没有好方法。按照逻辑,您应该能够执行类似的操作

    PowerMockito.whenNew(File.class).withParameterTypes(String.class)
                                    .withArguments(eq(WORKING_PATH)).thenCallRealMethod();
    

    但是这会在 PowerMockito 中触发类似这样的内部异常

    org.mockito.exceptions.base.MockitoException:无法在 java 对象上调用抽象真实方法!只有在模拟非抽象方法时才能调用真实方法。 //正确的例子:when(mockOfConcreteClass.nonAbstractMethod()).thenCallRealMethod();

    因此,我能看到的唯一方法是重新编写测试。在模拟构造函数之前,您应该首先构造所有需要的 File 对象,并给出在每种特定情况下要返回的 PowerMockito 规则。

    File mocked = Mockito.mock(File.class);
    // create file as you want
    File realFile = new File(WORKING_PATH);
    // tell PowerMockito to return it
    PowerMockito.whenNew(File.class).withParameterTypes(String.class)
                .withArguments(Mockito.eq(WORKING_PATH)).thenReturn(realFile);
    // tell PowerMockito to return mock if other argument passed
    PowerMockito.whenNew(File.class).withParameterTypes(String.class)
                .withArguments(Mockito.eq(THE_TARGET_PATH)).thenReturn(mocked);
    
    File normalFile = new File(WORKING_PATH);
    File mockedFile = new File(THE_TARGET_PATH);
    

    这是不受欢迎的解决方案,但我无法提供更好的解决方案。

    希望对你有帮助!

    【讨论】:

    • 谢谢,我已经在做这个“解决方法”了。似乎 Powermock 无法做得更好。但是,在我将此答案标记为已接受之前,让我们等待更多答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-31
    • 1970-01-01
    相关资源
    最近更新 更多