1

I'm trying to use PowerMockito to mock a static class throwing an IOException. I'm using JUnit 4.12 and PowerMockMockito 1.6.3 in my package. However, I get an "initializationError" due to the "@RunWith(PowerMockRunner.class)" annotation I need to put above the class definition. This happens even if the test class is empty.

Here is the stack trace of the error:

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)

My attempts to solve the problem has led me to several older SO questions like this one, where a similar problem was resolved after PowerMockito was updated to 1.6.1. Unfortunately it was not very helpful.

I am new to PowerMockito, so I might be missing something too obvious to be mentioned in any guides. Any ideas on how I can resolve this? Thanks in advance.

Community
  • 1
  • 1
Pomacanthidae
  • 207
  • 1
  • 3
  • 8
  • 1
    In case my answer won't cut it, and you don't get any "real" answer here (what happens quite often) ... you could try here: https://groups.google.com/forum/#!forum/powermock - that is where the PM developers read. – GhostCat Sep 07 '16 at 04:38
  • can you update your test classes – kuhajeyan Sep 07 '16 at 06:27

1 Answers1

2

If the whole thing is your code, then a not so subtle solution would be: avoid PowerMock, and this sort of problems completely. Instead accept that static is an abnormality in good OO designs - as it leads to direct, hard coupling of your classes.

So instead of writing hard-to-test code that requires the big Powermock hammer in order to be testable: come up with code that avoids static; and that thus can be tested without the need for Powermock.

Long story short: learn about writing testable code (for example by listening to these [videos][1]). And let the door to the Powermock room closed. And when that static thingy lives in external code that you don't own; you might still put a wrapper around it and avoid the direct dependency.

Edit: of course, it is cumbersome to work around such a central thing as Apache commons, but still, you can always do something like:

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

you can forward and "interface" this:

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

Then you have a simple

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

And, now within your client class:

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

This code allows you:

  1. keep using the existing static methods with minimal overhead
  2. pass mocked instances of TheStaticThingFunctionality into your Client class

And now you can fully control when you exceptions to fly; and more importantly: you already made a first step towards decoupling yourself from the implementation provided by Apachace commons - as you are now free to exchange TheStaticThingImpl with something else if you see a need for that!

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • Can you please elaborate more? What I'm trying to do is to merge a bunch of files into a single file. I'm using the Apache Commons FileUtils library to do this, and the read/write operations I use can all cause a IOException. If an exception occurs I need to revert everything into its original state, which means erasing the semi-completed merged file. It looks like I don't have much choice but to deal with the exception. – Pomacanthidae Sep 12 '16 at 21:02