Mocking a class object using Mockito and PowerMockito

why not using an agent if you can't refactor the code there isn't many options, as @jherics mentionned, java system classes are loaded by the bootstrap classloader and powermock can't redefine their bytecode.

However Powermock now coms with an agent, that will allow system classes mock. Check here for complete explanation.

The main idea is to modify your java command and add :

-javaagent: path/to/powermock-module-javaagent-1.4.12.jar

The basic thing this agent is doing is to definalize classes, to allow future mocking in a specific test, that's why you'll need to use specific types to communicate with the agent, for example with JUnit :

@Rule PowerMockRule rule = new PowerMockRule(); // found in the junit4 rule agent jar

TestNG is also supported. Just check the wiki page for more information.

Hope that helps.


An alternative to mocking Class might be to use a Factory instead. I know you are concerned about refactoring, but this could be done without changing the public API of the class. You haven't provided much code to understand the class you are trying to test, but here's an example of refactoring without changing the API. It's a trivial class, but it might give you an idea.

public class Instantiator {

  public Runnable getNewInstance(Class<Runnable> runnableClass) throws Exception {
    return runnableClass.newInstance();
  }
}

Of course, the easiest thing to do to test this trivial class would be to use a genuine Runnable class, but if you tried to mock the Class, you would run into the problems you're having. So, you could refactor it thus:

public class PassThruFactory {
  public Object newInstance(Class<?> clazz) throws Exception {
    return clazz.newInstance();
  }
}

public class Instantiator {
  private PassThruFactory factory = new PassThruFactory();

  public Runnable getNewInstance(Class<Runnable> runnableClass) throws Exception {
    return (Runnable)factory.newInstance(runnableClass);
  }
}

Now Instantiator does exactly the (trivially simple) thing it was doing before with the same public API and no need for any client of the class to do any special injecting of their own. However, if you wanted to mock the factory class and inject it, that's very easy to do.