21

I am working on a project where we are currently doing testing with JUnit and Mockito. Now I am trying to find out what would be the side effects of adding PowerMock to the mix.

What are its disadvantages, any dependencies I should know about, any stability issues?

I saw it supports Java 8. Are there any issues there? From what I've read, getting Java 7 support was quite a long road.

EDIT: I guess a questions that would sum it all would be:

What would be the reasons to not use PowerMock?

KKO
  • 1,913
  • 3
  • 27
  • 35
  • Can you be a bit more specific in what way you fear that PowerMock might not be reliable? – Uwe Allner May 11 '15 at 07:50
  • Also, please limit the amount of questions to one, or at least to one concept, as it stands now, the post falls squarely into the ["unclear what you're asking" category](http://stackoverflow.com/help/closed-questions). – mikołak May 11 '15 at 07:54
  • I hope now it's a bit more clear. And it also says on their homepage "Putting it in the hands of junior developers may cause more harm than good." – KKO May 11 '15 at 08:04
  • Are you sure you really need it ? Are you working on legacy code ? – gontard May 11 '15 at 08:06
  • For starters, nearly all the things you'd need PowerMock for are code smells. – chrylis -cautiouslyoptimistic- May 11 '15 at 08:37
  • @chrylis And what about the things that are *not* code smells? Should I then compromise the design of my code in order to work around some arbitrary limitation in a specific mocking library? Is that what you propose? – Rogério May 17 '15 at 16:28
  • @Rogério Exceptions exist but are few and far between. If your methods make sense as statics, then they don't need to be modified to be tested. The limitation isn't of the mocking library itself; it's in the attempt to compromise the semantics of language features (such as the concept of "static") instead of thinking about whether, for instance, global configuration of an entire API really makes sense. – chrylis -cautiouslyoptimistic- May 17 '15 at 17:14
  • @chrylis For a concrete example, I have mocked the JSF `FacesContext.getCurrentInstance()` method, in real-world tests. It was easy and clean, so why not? How would you solve this problem, if you had to write a test for a JSF-based class which happened to use the `FacesContext` object? – Rogério May 17 '15 at 17:28
  • @Rogério I'd probably do just what you did. That doesn't negate the fact that the stateful static provider is a flaky design. – chrylis -cautiouslyoptimistic- May 17 '15 at 17:39
  • @chrylis I guess we agree then: when the design can be improved to, for example, eliminate statics, we should do that; if that's not an option or is not the case (ie, we want to mock a well-designed API having `final` classes or methods, or mock an internally-instantiated stateful object), then we would use a mocking tool that can do the job. – Rogério May 18 '15 at 16:33

1 Answers1

67

Generally if you start new project and you (want to/ are forced) to use PowerMock because of the architecture of your code it means that this architecture is bad and needs improvement. Power Mock gives you access to mock static methods, constructors etc. and this means that your code is not following best programming principles.

Power Mock should be used in legacy applications where you cannot change the code which has been given to you. Often such code does not have unit/integration tests and even small change can result in bugs in application.

wsl
  • 8,875
  • 1
  • 20
  • 24
  • 8
    This is the most appropriate answer. Power Mock is a (very useful) specialty tool for making legacy, smelly, or otherwise "difficult" code testable (a good example that is not a code smell would be mocking `final` classes), using it extensively in an actively developed code base might be a sign of a problem. – mikołak May 11 '15 at 09:03
  • 2
    Ok, I understand that powermock should be used only for legacy code and not new projects. What I don't understand is the "why"? Do any issues arise if you use it on new projects? There can sometimes be static classes, maybe even final, that need to be tested, right? – KKO May 11 '15 at 09:24
  • It is mostly about code design. Nice and clean code does not demand to have f.e static methods which are hardly testable. Apart from using them use lightweight and loosely coupled services. See http://stackoverflow.com/questions/871434/java-utility-class-vs-service. But of course it depends on what you want to achieve in your system. – wsl May 11 '15 at 13:21
  • 3
    So, object-oriented code does not fit "best programming principles"? Say, how would I unit test a class "A" which instantiates and uses a stateful class "B"? For example, if "A" uses `java.net.URL`, `org.apache.commons.mail.SimpleMail`, or another stateful application class? And what about classes made `final`, following the well-known API design principle of "design for inheritance or prohibit it" (from the "Effective Java" book)? – Rogério May 17 '15 at 16:24
  • It is not the discussion about how to test final classes and stateful classes but about using PowerMock so do not miss the point. PowerMock indeed should not be used extensively when there is no point in doing it and can be avoided. Check how long it took PowerMock to make it compatible with Java 7 as it is using javassist for manipulating byte code. – wsl May 17 '15 at 16:48
  • 4
    So basically you're saying that any Java with static methods or final methods / classes is considered bad code. Why are those constructs even in the language then if they are to never be used? – Ozymandias Oct 24 '19 at 17:51
  • 2
    @wsl If statics are bad to use, think about a case of writing a utility library which has all static methods(coz its utility), how to test these methods then ? – Piyush Kumar Dec 20 '19 at 10:55
  • @PiyushKumar I do not see a correlation. You can test such libraries using JUnit tests ? What is the point of using power mock in such case ? – wsl Dec 31 '19 at 09:03
  • 1
    I totally disagree. You are telling that static methods are bad. How do you implement helper methods then? Going to create an instance though it is not required? isn't this a bad code? – explorer May 29 '21 at 07:23
  • static methods are not bad if they are utilities. They are bad if they are using some hardwired dependencies in them. Example: StringHelper to return you a custom hash of a string or that checks NullOrEmpty are not using some external dependencies in their business logic. So, they can remain static. But, if you have a static method say: UserService.saveUser(user) and that uses UserDao as a dependency, then you have a problem to test saveUser method without worrying about what UserDao is doing. Hope that helps. – Deepak Mar 14 '22 at 19:04