These specs seem very coupled to the implementation, and limit how much we can refactor the code.

I think mocking works really well when you're working with objects with very narrow interfaces (particularly if you define them), but these ruby objects have _very_ wide interfaces and we may want to refactor the implementation to use a different File/IO APIs.

I'd rather see you spec this with some mini-integration tests that actually write out to the file system.  The specs will be much less brittle, and while it's a good idea to avoid hitting the file system in tests when you can, it doesn't worry me much here and will still be quite fast.