PowerMockRunner初始化错误

时间:2016-09-06 20:43:08

标签: java junit powermockito

我正在尝试使用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的新手,所以我可能会遗漏任何指南中太明显无法提及的内容。关于如何解决这个问题的任何想法?提前谢谢。

1 个答案:

答案 0 :(得分:2)

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

所以不要编写需要大型Powermock锤子才能测试的难以测试的代码:提出避免静态的代码;因此可以在不需要Powermock的情况下进行测试。

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

编辑:当然,解决像Apache公共这样的核心问题是很麻烦的,但是,你仍然可以总是做类似的事情:

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

你可以转发&#34;界面&#34;这样:

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; }

此代码允许您:

  1. 以最小的开销继续使用现有的静态方法
  2. 将模拟的TheStaticThingFunctionality实例传递到您的Client类
  3. 现在,您可以完全控制何时飞行例外;更重要的是:你已经迈出了迈向Apachace公共提供的实现的第一步 - 因为如果你看到需要的话,你现在可以自由地用其他东西交换TheStaticThingImpl!

相关问题