Hacker News new | ask | show | jobs
by ZoFreX 4201 days ago
"PowerMock is basically only for tests that interact with badly designed code that you can't change"

Presumably where the definition of badly designed includes "uses static methods"? That's something that I hold true, and teach to other people as true, but I have started wondering about it. Whenever I ask why it's bad I get told "it makes testing hard". Well, Powermock can make testing it possible - "but powermock is only for badly designed code". What's badly designed code? And so it goes round.

Is it really that conceptually bad? Or is it just that our testing tools are insufficient, or that the language itself did not make provisions for testing all of its features? I've seen a lot of code recently that uses dependency injection purely for testing, and uses builders instead of constructors all over the place, and it feels like a lot of effort and complexity to avoid using PowerMock.

1 comments

It's not just about testing, though that's where you tend to run into it first. Statics and constructors are both second-class citizens in Java: they can't conform to interfaces, so there's no way to separate interface and implementation when using them, no way to hide information, no way to invert control or any of the other principles of good design.

(Of course, Java was designed by people doing the best they could subject to particular constraints, and is now constrained by backwards compatibility. But other languages provide the same kind of features in better ways (or provide syntax that means builders and dependency injection are much less effort, depending on which way you look at it))

Pragmatically, good design is not the only concern; if you're not writing a library with binary-compatibility concerns, then IMO the syntactic overhead of builders is often a cost that outweighs the benefits. But the design costs of statics and constructors in Java are real enough, and there are very direct costs to using PowerMock (tests are harder to maintain and more brittle as they have to specify which classes they're rewriting, and it can conflict with other things that do bytecode manipulation e.g. test coverage tools).