3

I'm currently reading "Working Effectively with Legacy Code" by Michael Feathers.

So far, a lot of techniques the book mentions, start with a problem similar to: "it's really difficult / it would take too long to get the class into a test harness..." Then the book goes on to suggest a technique to work-around this problem.

Lately, I've been working with Jmockit library and it lets you mock pretty much anything you'd like in a pretty easy way.

In that case, doesn't it make the aforementioned techniques redundant?

Thanks!

2
  • 1
    You could say that. You could also say that working effectively with legacy code makes jmockit redundant. Just how dependent do you want your code to be on jmockit? Say versus a being dependent on creating a decoupled design? Commented Sep 4, 2016 at 9:23
  • Let me ask you a question, have you using your mocking library on new code, or legacy code? If working with legacy code, I can hardly believe that you've not run into a situation where you had to refactor just to make a dependency mockable.
    – RubberDuck
    Commented Sep 4, 2016 at 11:30

1 Answer 1

4

While JMockit does allow you to work around a lot of problems, there are two things you need to consider: it will not work for every language out there and it might simply be the wrong solution.

JMockit relies on a number of techniques that work, but that are not language-independent. While every object-oriented language out there will allow you to pass a class into a method and call a method on that class (dependency injection), not every language will allow you to mock or fake every call made. "Working effectively with legacy code" has samples in Java, but the book isn't about solving this problem in Java alone. It can be, and is applied, in a variety of languages.

It is also sometimes the wrong solution simply because a testable design is often a good design. Let's assume that you have a class that contains a number of public methods which all use a single, 100-line long private method to prepare data. Unittesting this one class can be problematic: you want to test the logic in the public methods, but that also involves testing the private method. And testing the private method can only be achieved through the public methods, which makes testing hard. Extracting the private method into a separate class and dependency-injecting it not only makes the class more testable, but also makes the class with the remaining methods clearer: it can be smaller, more focused and easier to understand.

2
  • Doesn't this lead to an inflexible design. Previously that private method was encapsulated and entitled to change (perhaps for performance). Now it's part of the signature of the class and shouldnt change. Personally I think private methods should only be tested via the public methods and any attempt to test them directly is a mistake Commented Sep 4, 2016 at 12:56
  • If you have a single, 100-line private method that is used by other methods chances are it makes a lot of sense to extract this method into a separate class. Especially if that method contains a lot of logic. If your big method has two main branches and is private, every test of your public method has to be duplicated to include both branches on the private method.
    – JDT
    Commented Sep 4, 2016 at 13:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.