Saturday, September 18, 2010

I was just thinking about how I would write some test-first code in an interview, and it reminded me of using factories and mocking, and how I couldn't defend mocking to a smart young developer who had just given a talk about optimizing the performance of tests. I tried to explain why I liked it but my reasons seemed too abstract for him to buy into it. He said that letting his tests run through his whole app, it made him think everything was really working. I think he also suspected mocking would lead him to have to do more work on tests. Keep in mind that this was someone who had clearly already rewritten his tests many times in a relatively short testing career.

What if I told him it was like your app is a car, and you're testing the car. Wouldn't you want to test the individual parts, instead of waiting until the car is built? Unit testing does this, but what about when you are testing the conduit between two complex tools? Without mocking, you sacrifice your ability to inspect what is happening inside those two tools as they interact. I see the mock as a piece of specialized machinery that is designed to simulate part of your car, but is also letting you watch and measure things with as much precision as you need.

The app is also like a car in that some parts of it are there to go fast, some parts are there to keep you safe, and some parts are just there to smooth out the ride. They all need to be tested for different reasons, and sometimes it will make sense to test them in different ways. Conventions are important but if you think about it, every object has the potential for doing something unique; and you may be better able to express and use that potential if you don't hold to any presuppositions about how you are going to test something.

Cars have been made great largely because of the simplicity of decoupling the individual parts, at least to a certain extent, and seeing how each one performs in different environments. Maybe rubber tires were first used for horse buggies, and steel wheels were first used for streetcars. The tires for the Model T were sort of a hybrid; and the wheels for every car or vehicle made since then have been further hybridizations of that same tool. The point is partly that if your business is successful, your application is going to develop enough complexity to keep you coming back to the code and adding new ways to handle things. The real world is complex, and to make something truly useful you have to really marry it to the real world. Think of all the new safety regulations cars have had to meet over the years. Cars today can have 3000 or more parts. But a production application can have 3000 or more files. If you are successful, it depends on the app, but I'd bet most projects will get there if they are celebrating their tenth or twentieth birthday. Think of all the times you'll have to rewrite your tests to get through the next ten years. I think that's just how it is in a successful business, there's a lot of changes involved in achieving that appearance of stability. But that's one of the reasons that mockists like being able to describe their needs in more general, or abstract, terms, instead of only working with the side effects of a particular implementation. There is a circular logic problem, so using mocks does leave you the onus of verifying that your app pieces can actually work together. Even so, mocks can be the perfect method for combining several components in a test, and for limiting it to the ones you want. This is also a big reason why I like rr ("double r"). You can use mock.proxy to make sure your method is called the right way, and also pass the method down the chain to see what happens, right there in the same test. It's quite amazing.

So maybe this is just more abstract bs, but I think that mocking makes my app better by letting me see to it that everything makes sense, not just that it seems to work for some reason. Spending more time with the surfaces of my objects may be a hefty trade-off, but I think it will end up saving me time in the long run. Hopefully I will have a better idea after 10 more years of experience.

0 Comments:

Post a Comment

<< Home