17. Example
• Restaurant system reserves tables
• Instead of your interface talking to a
ReservationService:
• Talk to ReservationInterfaceHandler
18. Message Example
class ReservationInterface
def initialize(handler)
@handler = handler
end
def select_table(table)
@table = table
end
def submit_request
@handler.reserve(@table)
end
end
19. And to Spec it
describe ReservationInterface do
let(:table){something_interesting_here}
it "should tell the handler to reserve a table" do
handler = double('reservation_handler')
handler.should_receive(:reserve).with(table)
machine = ReservationInterface.new(handler)
machine.select_table(table)
machine.submit_request
end
23. Other Mock Smells
• Having to setup more than 3 lines -- that’s a
code smell
24. Other Mock Smells
• Having to setup more than 3 lines -- that’s a
code smell
• Mocking concrete objects -- that’s a code
smell
25. Other Mock Smells
• Having to setup more than 3 lines -- that’s a
code smell
• Mocking concrete objects -- that’s a code
smell
• When tests go brittle and developers
declare mocks suck -- that’s a code smell
27. However
• If you have a “standard” Rails app,
programmed procedurally:
28. However
• If you have a “standard” Rails app,
programmed procedurally:
• Mocks are not for you
29. However
• If you have a “standard” Rails app,
programmed procedurally:
• Mocks are not for you
• If you encapulate your code. If you hide
information (OOP). If you use messages:
30. However
• If you have a “standard” Rails app,
programmed procedurally:
• Mocks are not for you
• If you encapulate your code. If you hide
information (OOP). If you use messages:
• Mocks are for you!
33. Mocks Don’t Suck
• If your code is hard to test, you need better
code
• If you have a test that is HARD to setup,
your class (or test) is doing too much
34. Mocks Don’t Suck
• If your code is hard to test, you need better
code
• If you have a test that is HARD to setup,
your class (or test) is doing too much
• If you see tests with uber-mocks, the
answer is not to delete mocks. It’s to
isolate your tests
45. Avoid Factories
• Instead, extract your code to classes with
one single responsibility
• Rather than knowing everything about your
object
46. Avoid Factories
• Instead, extract your code to classes with
one single responsibility
• Rather than knowing everything about your
object
• Or, load methods via modules
54. What then?
• Your models can have validations
• Call out to policy or decision classes for
business logic
55. What then?
• Your models can have validations
• Call out to policy or decision classes for
business logic
• Use Ruby Classes
56. What then?
• Your models can have validations
• Call out to policy or decision classes for
business logic
• Use Ruby Classes
• Use Presenters
57. Example
• Example of building a burrito that is
delicious, and can know it’s delicious
• In Isolation: https://gist.github.com/1281093
• Using Modules: https://gist.github.com/
1281064
58. Credits
Why you don’t get mock objects @gregmoeck
Your tests are lying to you @chrismdp
Fast Rails talk at gogoruco 2011 @coreyhaines
Testing in Isolation.
@garybernhardt
destroyalldoftware.com