TDD: Mocking out tightly coupled objects

couplingmockingtdd

Sometimes objects just need to be tightly coupled. For example, a CsvFile class will probably need to work tightly with the CsvRecord class (or ICsvRecord interface).

However from what I learned in the past, one of test-driven development's main tenets is "Never test more than one class at a time." Meaning you should use ICsvRecord mocks or stubs rather than actual instances of CsvRecord.

However after trying this approach, I noticed that mocking out the CsvRecord class can get a little hairy. Which leads me to one of two conclusions:

  1. It's hard to write unit tests! That's a code smell! Refactor!
  2. Mocking out every single dependency is just unreasonable.

When I replaced my mocks with actual CsvRecord instances, things went much more smoothly. When looking around for other peoples' thoughts I stumbled across this blog post, which seems to support #2 above. For objects that are naturally tightly coupled, we should not worry so much about mocking.

Am I way off track? Are there any downsides to assumption #2 above? Should I actually be thinking about refactoring my design?

Best Answer

If you really need coordination between those two classes, write a CsvCoordinator class that encapsulates your two classes, and test that.

However, I dispute the notion that CsvRecord is not independently testable. CsvRecord is basically a DTO class, is it not? It's just a collection of fields, with maybe a couple of helper methods. And CsvRecord can be used in other contexts besides CsvFile; you can have a collection or array of CsvRecords, for example.

Test CsvRecord first. Make sure that it passes all of its tests. Then, go ahead and use CsvRecord with your CsvFile class during test. Use it as a pre-tested stub/mock; fill it with relevant test data, pass it to CsvFile, and write your test cases against that.

Related Topic