我正在尝试使用PowerMockito模拟抛出IOException的静态类。我在我的程序包中使用JUnit 4.12和PowerMockMockito 1.6.3。但是,由于需要在类定义上方添加“ @RunWith(PowerMockRunner.class)”注释,因此出现“ initializationError”。即使测试类为空,也会发生这种情况。

这是错误的堆栈跟踪:

org.powermock.reflect.exceptions.FieldNotFoundException: Field 'fTestClass' was not found in class org.junit.internal.runners.MethodValidator.
at org.powermock.reflect.internal.WhiteboxImpl.getInternalState(WhiteboxImpl.java:581)
at org.powermock.reflect.Whitebox.getInternalState(Whitebox.java:308)
at org.powermock.modules.junit4.internal.impl.testcaseworkaround.PowerMockJUnit4MethodValidator.validateTestMethods(PowerMockJUnit4MethodValidator.java:97)
at org.powermock.modules.junit4.internal.impl.testcaseworkaround.PowerMockJUnit4MethodValidator.validateInstanceMethods(PowerMockJUnit4MethodValidator.java:67)
at org.junit.internal.runners.MethodValidator.validateMethodsForDefaultRunner(MethodValidator.java:51)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.validate(PowerMockJUnit44RunnerDelegateImpl.java:108)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.<init>(PowerMockJUnit44RunnerDelegateImpl.java:70)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.createDelegatorFromClassloader(JUnit4TestSuiteChunkerImpl.java:156)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.createDelegatorFromClassloader(JUnit4TestSuiteChunkerImpl.java:40)
at org.powermock.tests.utils.impl.AbstractTestSuiteChunkerImpl.createTestDelegators(AbstractTestSuiteChunkerImpl.java:244)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.<init>(JUnit4TestSuiteChunkerImpl.java:61)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.<init>(AbstractCommonPowerMockRunner.java:32)
at org.powermock.modules.junit4.PowerMockRunner.<init>(PowerMockRunner.java:34)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
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:59)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:33)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.<init>(JUnit4TestReference.java:33)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestClassReference.<init>(JUnit4TestClassReference.java:25)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:48)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:444)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)


我试图解决该问题的尝试导致我遇到了一些较旧的SO问题,例如this,在PowerMockito更新到1.6.1之后,解决了类似的问题。不幸的是,它不是很有帮助。

我是PowerMockito的新手,所以我可能缺少任何指南中都未提及的明显内容。关于如何解决此问题的任何想法?提前致谢。

最佳答案

如果整个事情都是您的代码,那么一个不太微妙的解决方案是:
避免使用PowerMock,完全避免此类问题。相反,要接受静态是好的OO设计中的异常-因为它会导致类的直接,硬耦合。

因此,与其编写难于测试的代码,而需要使用强大的Powermock锤才能进行测试,不如编写:避免静态的代码;因此无需Powermock即可对其进行测试。

长话短说:学习编写可测试的代码(例如,通过听这些[视频] [1])。然后关上Powermock房间的门。当静态的东西存在于您不拥有的外部代码中时;您可能仍然需要使用包装器,并避免直接依赖。

编辑:当然,解决诸如Apache commons这样的核心问题很麻烦,但是仍然可以执行以下操作:

class TheStaticThing {
  public static Whatever doSomething(Somethin els) throws StupidException { ...


您可以转发和“接口”此:

interface TheStaticThingFunctionality {
  public static Whatever doSomething(Somethin els) throws StupidException;


然后你有一个简单的

class TheStaticThingImpl implements TheStaticThingFunctionality {
  @Override
  public Whatever doSomething(Somethin els) throws StupidException {
     return TheStaticThing.doSomething(els);
  }


而且,现在在您的客户类别中:

class Client {
   private final TheStaticThingFunctionality func;
   Client() { this(new TheStaticThingImpl()); }
   Client(TheStaticThingFunctionality func) { this.func = func; }


此代码允许您:


以最小的开销继续使用现有的静态方法
将模拟的TheStaticThingFunctionality实例传递到Client类


现在,您可以完全控制何时例外飞行。更重要的是:您已经迈出了将自己与Apachace公用程序提供的实现脱钩的第一步-因为现在您可以自由地将TheStaticThingImpl与其他东西交换!

关于java - PowerMockRunner初始化错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39357534/

10-10 22:18