关于java:Powermockito whenNew如果不匹配则返回null

Powermockito whenNew returns null if not matched

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

1
2
3
4
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将正常创建,但实际上是nullmockedFile已正确模拟。

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

我正在使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<dependency>
        <groupId>org.powermock</groupId>
        powermock-module-junit4</artifactId>
        <version>1.7.4</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.powermock</groupId>
        powermock-api-mockito</artifactId>
        <version>1.7.4</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.powermock</groupId>
        powermock-core</artifactId>
        <version>1.7.4</version>
        <scope>test</scope>
    </dependency>

我的发现表明,没有一种好的方法可以使用PowerMockito / PowerMockito 2进行部分构造函数模拟。通过逻辑,您应该能够执行类似

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

但这会在PowerMockito中触发类似于此的内部异常

org.mockito.exceptions.base.MockitoException: Cannot call abstract real method on java object! Calling real methods is only possible when mocking non abstract method. //correct example: when(mockOfConcreteClass.nonAbstractMethod()).thenCallRealMethod();

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

1
2
3
4
5
6
7
8
9
10
11
12
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);

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

希望能帮助到你!