From: Gregory Brown Date: 2008-08-02T07:19:50+09:00 Subject: Re: unit testing advice On Fri, Aug 1, 2008 at 6:03 PM, Shadowfirebird wrote: > Many thanks. Clearly I'm going to have to go back to research mode on > this one. > > I've found this lovely bit of example code for mocha, though -- see > below. If I understand you correctly, you seem to be saying that you > *don't* test the output routine; you use a mock to fake it so that you > can test the rest of the code? Mocks do check to make sure that certain calls are actually made with constraints on the way they are called and how they respond. So if you have a method like load_text_file(name) that appends a .txt to the end of the filename and then reads the file, like so: def load_text_file(name) File.read("#{name}.txt") end You'd want to do a mock like: # Set up the expectation File.expects(:read).with("foo.txt") load_text_file "foo" The point here is that this tests your code without unnecessarily verifying that File.read() works. Of course, be sure that your mocks reflect reality when you design them, as it's possible to build nonsense mocks that lead you astray. However, as soon as you really try to use your code, you'd notice that and be able to fix it in your tests... > That would imply that you farm out the difficult bits of the output > routine into other methods in the same way that you would with > functional programming -- ideally, leaving the output routine as > something that is so simple it doesn't need testing? Essentially the idea behind mocking is that you replace an external resource with an object that handles the sorts of messages that form the interface between your external resource and your code. This should behave in the same way you'd expect your real resource to behave given the way that you are using it, so that you can test things like exception handling and also test your code that wraps and invokes these resources. From this point of view, the assumption is that you can rely on thing like File handles, Database connections, or other external resources to work as expected, so you don't need to actually test them directly. What you do need to test is the interaction between your code and these resources, and for this purpose, a suitable mock object that verifies these things works great. And yes, testing this way does encourage you to make your wrappers of external resources clean and easy to work with, which is a side benefit. -greg -- Killer Ruby PDF Generation named after a magnificent sea creature: http://github.com/sandal/prawn | Non-tech stuff at: http://metametta.blogspot.com