RubyConf 2011 | 2011-09-29 | Gregory Moeck (@gregmoeck)
- Recommended as the best book on mocks: Growing Object-Oriented Software, Guided by Tests by Steve Freeman & Nat Pryce
- Common arguments against mocks
- They duplicate implementation
- They lead to brittle tests
- Mock objects + procedural programming = bad idea
- If you're doing traditional Rails development (which tends to follow more of a "procedural", do-this-and-then-do-that style), mock objects probably aren't for you
- Mocks are not stubs
- When you're asserting on state, you're stubbing
- When you're asserting on messages between objects, you're mocking
- Emphasized specific OO principles
- Tell, don't ask (i.e., commands)
- Hides internal state (i.e., no getters)
- If you have these principles in play, you cannot assert on state
- You could add getters just for the tests, but that's a bad idea
- Instead, use mocks to assert on the message going between objects
- Key mocking rules
- Mock roles, not objects
- Wanting to mock concrete objects is a design smell
- Well designed objects don't know explicitly who they're talking to
- They should only know the role that their collaborator is playing
- When mocking roles, TDD becomes a design process
- Helps you follow the Single Responsibility Principle
- Only mock types that you own
- If you don't own the API, there is no design feedback that you'll get by writing a test for it
- Instead of mocking a role, you're mocking an implementation
- You're duplicating production code in a test, and this is a test smell
- Only mock peers, not internals
- Decide what is inside and what is outside your object
- Not everything belongs to a peer
- Ask yourself, "Is this the role that this object is supposed to play?" If so, the behavior is internal to the object and should therefore not be mocked.
- Mock roles, not objects