使用 JDK 8 运行 powermockito 时出现 org.objenesis.ObjenesisException

问题描述

我正在尝试使用 powermockito 在我的单元测试用例中模拟文件读取, 下面是我要测试的代码

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;

public class FileOperation {

    public List<String> readFromFile( String inputFilePath ) throws IOException {
         List<String> lines = Files.readAllLines(Paths.get(inputFilePath));
        
        return lines;
    }
    
    public void writeIntoFile(String result,String outputFilePath) throws IOException {
        Files.write(Paths.get(outputFilePath),result.getBytes());
        
    }
}

下面是我的测试用例文件

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;


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)
@PrepareForTest(FileOperation.class)
public class FileOpertionTest {

    
    @Before
    public void setUp() throws Exception {
        
    }


    
    @Test
    public void readFromFileTests() throws IOException {
        //BufferedReader br= powermockito.mock(BufferedReader.class);
        
        //powermockito.mockStatic(Paths.class);
        powermockito.mockStatic(Files.class);
        List<String> lines = new ArrayList<String>() {{
            add("data1");
            add("data2");
            add("data13");
        }};
        
        Mockito.when(Files.readAllLines(Paths.get("somePath"))).thenReturn(lines);
        
        FileOperation fileOperation = new FileOperation();
        List<String> listofWords = fileOperation.readFromFile("somePath");
        assertEquals(listofWords.size(),3);
    }

}

下面是我的 maven 依赖。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>clientProject</groupId>
  <artifactId>clientProject</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>clientProject</name>
  
  <dependencies>
<dependency>  
    <groupId>org.powermock</groupId>  
    <artifactId>powermock-api-mockito</artifactId>  
    <version>1.7.0</version>  
    <scope>test</scope>  
</dependency>  
  
<dependency>  
    <groupId>org.powermock</groupId>  
    <artifactId>powermock-module-junit4</artifactId>  
    <version>1.7.0</version>  
    <scope>test</scope>  
</dependency>

  </dependencies>
</project>

但是在运行时我遇到了异常

org.objenesis.ObjenesisException: java.lang.reflect.InvocationTargetException
    at org.objenesis.instantiator.sun.SunReflectionFactoryHelper.newConstructorForSerialization(SunReflectionFactoryHelper.java:55)
    at org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.<init>(SunReflectionFactoryInstantiator.java:38)
    at org.objenesis.strategy.StdInstantiatorStrategy.newInstantiatorOf(StdInstantiatorStrategy.java:58)
    at org.objenesis.ObjenesisBase.getInstantiatorOf(ObjenesisBase.java:91)
    at org.powermock.reflect.internal.WhiteBoxImpl.newInstance(WhiteBoxImpl.java:259)
    at org.powermock.reflect.WhiteBox.newInstance(WhiteBox.java:139)
    at org.powermock.tests.utils.impl.AbstractTestSuiteChunkerImpl.getPowerMockTestListenersLoadedByASpecificclassLoader(AbstractTestSuiteChunkerImpl.java:95)
    at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.createDelegatorFromClassloader(JUnit4TestSuiteChunkerImpl.java:174)
    at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.createDelegatorFromClassloader(JUnit4TestSuiteChunkerImpl.java:48)
    at org.powermock.tests.utils.impl.AbstractTestSuiteChunkerImpl.createTestDelegators(AbstractTestSuiteChunkerImpl.java:108)
    at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.<init>(JUnit4TestSuiteChunkerImpl.java:71)
    at org.powermock.modules.junit4.common.internal.impl.AbstractCommonpowermockrunner.<init>(AbstractCommonpowermockrunner.java:36)
    at org.powermock.modules.junit4.powermockrunner.<init>(powermockrunner.java:34)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481)
    at org.junit.internal.builders.AnnotatedBuilder.buildrunner(AnnotatedBuilder.java:104)
    at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:86)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:70)
    at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:37)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:70)
    at org.junit.internal.requests.ClassRequest.createRunner(ClassRequest.java:28)
    at org.junit.internal.requests.MemoizingRequest.getRunner(MemoizingRequest.java:19)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createUnfilteredTest(JUnit4TestLoader.java:90)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:76)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:49)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:526)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:770)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
Caused by: java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at org.objenesis.instantiator.sun.SunReflectionFactoryHelper.newConstructorForSerialization(SunReflectionFactoryHelper.java:45)
    ... 31 more
Caused by: java.lang.IllegalAccessError: class jdk.internal.reflect.ConstructorAccessorImpl loaded by org.powermock.core.classloader.MockClassLoader @68c4039c cannot access jdk/internal/reflect superclass jdk.internal.reflect.MagicAccessorImpl
    at java.base/java.lang.classLoader.defineClass1(Native Method)
    at java.base/java.lang.classLoader.defineClass(ClassLoader.java:1017)
    at org.powermock.core.classloader.MockClassLoader.loadUnmockedClass(MockClassLoader.java:262)
    at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:206)
    at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass1(DeferSupportingClassLoader.java:89)
    at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:79)
    at java.base/java.lang.classLoader.loadClass(ClassLoader.java:522)
    at java.base/java.lang.classLoader.defineClass1(Native Method)
    at java.base/java.lang.classLoader.defineClass(ClassLoader.java:1017)
    at org.powermock.core.classloader.MockClassLoader.loadUnmockedClass(MockClassLoader.java:262)
    at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:206)
    at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass1(DeferSupportingClassLoader.java:89)
    at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:79)
    at java.base/java.lang.classLoader.loadClass(ClassLoader.java:522)
    at java.base/java.lang.classLoader.defineClass1(Native Method)
    at java.base/java.lang.System$2.defineClass(System.java:2196)
    at java.base/jdk.internal.reflect.ClassDefiner.defineClass(ClassDefiner.java:65)
    at java.base/jdk.internal.reflect.MethodAccessorGenerator$1.run(MethodAccessorGenerator.java:400)
    at java.base/jdk.internal.reflect.MethodAccessorGenerator$1.run(MethodAccessorGenerator.java:394)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:312)
    at java.base/jdk.internal.reflect.MethodAccessorGenerator.generate(MethodAccessorGenerator.java:393)
    at java.base/jdk.internal.reflect.MethodAccessorGenerator.generateSerializationConstructor(MethodAccessorGenerator.java:112)
    at java.base/jdk.internal.reflect.ReflectionFactory.generateConstructor(ReflectionFactory.java:462)
    at java.base/jdk.internal.reflect.ReflectionFactory.newConstructorForSerialization(ReflectionFactory.java:375)
    at jdk.unsupported/sun.reflect.ReflectionFactory.newConstructorForSerialization(ReflectionFactory.java:98)
    ... 36 more

我正在使用编译级别为 1.8 的 jdk 14 我看到一些帖子说 powermock 有更高 jdks 的问题,但我不确定我必须使用哪些依赖项才能使其工作?

更新 1:

从此 answer 更新我的 maven 依赖项

<dependency>
  <groupId>org.mockito</groupId>
  <artifactId>mockito-core</artifactId>
  <version>2.18.0</version> <!-- or higher,correspondning to powermock-version -->
</dependency>
<dependency>
  <groupId>org.powermock</groupId>
  <artifactId>powermock-api-mockito2</artifactId>
  <version>2.0.0-beta.5</version> <!-- or higher -->
</dependency>
<dependency>
  <groupId>org.powermock</groupId>
  <artifactId>powermock-module-junit4</artifactId>
  <version>2.0.0-beta.5</version> <!-- or higher -->
</dependency>

但现在我低于例外。

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.powermock.reflect.internal.WhiteBoxImpl (file:/C:/Users/vihan/.m2/repository/org/powermock/powermock-reflect/2.0.0-beta.5/powermock-reflect-2.0.0-beta.5.jar) to method java.lang.Object.finalize()
WARNING: Please consider reporting this to the maintainers of org.powermock.reflect.internal.WhiteBoxImpl
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
java.lang.RuntimeException: Internal error: Failed to find the "modifiers" field in method setInternalState.
    at org.powermock.reflect.internal.WhiteBoxImpl.sedModifiersToField(WhiteBoxImpl.java:2354)
    at org.powermock.reflect.internal.WhiteBoxImpl.removeFinalModifierIfPresent(WhiteBoxImpl.java:2318)
    at org.powermock.reflect.internal.WhiteBoxImpl.setField(WhiteBoxImpl.java:2304)
    at org.powermock.reflect.internal.WhiteBoxImpl.setInternalState(WhiteBoxImpl.java:304)
    at org.powermock.reflect.internal.WhiteBoxImpl.setInternalState(WhiteBoxImpl.java:317)
    at org.powermock.reflect.WhiteBox.setInternalState(WhiteBox.java:190)
    at org.powermock.modules.junit4.powermockrunner.run(powermockrunner.java:61)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:542)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:770)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
Caused by: java.lang.NoSuchFieldException: modifiers
    at java.base/java.lang.class.getDeclaredField(Class.java:2489)
    at org.powermock.reflect.internal.WhiteBoxImpl.sedModifiersToField(WhiteBoxImpl.java:2348)
    ... 12 more

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)