-- Brian Marick
When it comes to testing, there are a few people whose advice I seek out more often than others. Brian Marick is one of them (Martin Fowler and Steve Freeman are two others I can think of off the top of my head). So I'm excited to see what Brian has to say about Mocks.
"Object-oriented design is teaching objects what to say to each other." Nicely put.
Brian has a long and acrimonious history with mocks. He claims he finally got it... about six months ago.
"Mocks are about faster design and smoother pacing" relative to normal, everyday TDD.
Brian picks up his first example at the point that an AJAX request hits the server in a Sinatra application. The request will hit a JSON controller, which will go through several routines and then spit out some well-formed JSON over the wire. He uses Shoulda to test the JSON controller. He mocks out each object that the controller must interact with. Brian uses FlexMock (written by Jim Weirich) to mock out his objects. I wonder how this differs from Mocha. Should investigate this a little further.
After showing us the tests, he points out he can write code to pass the test without worrying about the creation or test-driving the objects that the controller utilizes. The idea here is that contrary to many people's usual one-way drive through TDD, mocking out the controller's objects first gives us the choice of what to create next.
As an aside, he's using something called Prezi Desktop, which I've never seen in action before. It seems like a cool, digitalized way of whiteboarding design.
For example, Brian next picks out the internalizer object. He test-drives that object, and then iteratively makes the controller actually "work" in the real world. The big win here is that as the internal functionality of the objects changes, your controller tests won't have to. The mock test simply ensures that the contract between the controller and the objects it interacts with stays broken. Checking out his slides (which will eventually be posted here.) will do better justice to this part of the talk than I can in prose. But I'll keep trying.
One interesting discovery Brian made was that when he finally felt comfortable with the way he was using mocks, he went back and replaced some of his tests with mock tests and was amazed at how much setup code and other cruft just "went away." I could definitely get down with that.
According to Brian: "Mocks are not about the final structure of the application. They are about the process by which you arrive at the final structure of the application." That seemed worth writing verbatim.
Faster Design: As the functionality of one of your controller's dependent objects grows, the size of the file grows too big. Probably the right thing to do here is to fork off another object, and continue to keep doing this (no shocker here: objects become too big or do too many things and must then be split into other objects). What Brian claims is that mocking "at the top" makes the construction of loosely coupled objects easier to design test-first.
Better Pacing: Again, this comes down to choice. Mock all of the objects that a controller must interact with on the controller test, and then defer the decision of which objects to construct, decompose, or change in any other way to the last responsible moment. Very cool idea. And very well illustrated in one particular slide. I need to try some of this out soon.
Mocks encourage you to start at the very top. Start at the view, or the controller, and drill down to the objects, the persistence layer, etc...
Brian points out the dirty little secret of mocks: in all likelihood it will force you to rewrite tests more than you are used to. But, he says, the rewriting is easier and even starts to feel like a natural part of the TDD flow. A bold statement, and one I'm willing to put to the test in my own work.
No comments:
Post a Comment