Question

While refactoring some old legacy code, I've tried to apply as much as possible the Single Responsibility Principle, so I ended up with many classes that have just one purpose. That's fine, but the problem comes when I tried to write unit tests for these new classes. Some classes are really hard to test, because the tests are hard to set up. I need to create like 4-5 mocks/stubs to write a single test case, and if I want to have all my code covered, I need to write several test cases so it's just a pain in the ass.

Having tests hard to set up (because it depends on many other classes) is a code smell? How do you solve this?

Was it helpful?

Solution

Here's what Uncle Bob says about SRP:

A class should have one, and only one, reason to change.

Note that it did not say "a class does one thing and only one thing." In other words, it's perfectly valid for a class to have more than one responsibility if all but one of those responsibilities are invariant or if they'll all change together.

In his Agile Patterns, Principles, and Practices book, Uncle Bob says:

In the context of SRP, we define a responsibility to be a reason for change (117).

And:

If, on the other hand, the application is not changing in ways that cause [multiple] responsibilities to change at different times, there is no need to separate them. Indeed, separating them would smell of needless complexity. (118)

That said, a class that has too many collaborators is a smell and should be examined carefully.

OTHER TIPS

  • You dont need ALL your code covered, use common sense
  • With small classes it should be easy to determine invariants, so populate them with asserts and let the code test itself
  • Split your system into layers and define where you can plug mock stimuli to put those asserts to work and verify outputs
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top