One of the fundamental tenets of Test-Driven / Behavior-Driven Development/Design is Don’t Mock What You Don’t Own (coined in the book Growing Object-Oriented Software, Guided by Tests by Steve Freeman and Nat Pryce).
Your example is violating this tenet: you don’t own
File, therefore you should not mock it.
Instead, what you could do is create your own abstraction for interacting with the file system, which only has the functionality you are actually requiring. Then you can create two implementations of this abstraction: one that uses Ruby’s
File class, and a mock one that does nothing. If you want to get fancy, you can even create one that simulates a file system in memory.
Of course, you have now just pushed the problem around: you now have untested code in your file abstraction implementation. However, ideally, this code should be “almost” trivial. And obviously, you can still have an integration test both for your file abstraction implementation, and also an integration test for
ConfigLoader that uses the real implementation instead of the mock or the simulation.
Here’s some further reading if you are interested:
- That’s Not Yours, Eric Smith (8th Light)
- Don’t mock what you don’t own, Testdouble.com
- TDD: Only mock types you own, Mark Needham (Neo4J)
- Don’t Mock What You Don’t Own, Maksim Ivanov
- Don’t Mock What You Don’t Own, Matt’s Codecave
- Don’t mock what you don’t own: a real world scenario, Giovanni Pinto
- Don’t mock types you don’t own, David Tchepak
CLICK HERE to find out more related problems solutions.