Fowler on Mocks

Colin Putney cputney at wiresong.ca
Tue Aug 8 23:37:30 UTC 2006


On Aug 8, 2006, at 5:23 PM, Hernan Tylim wrote:

> I think that Omnibrowser does use of Mock objects for testing.

OB-Tests-Core does have a class called OBProtocolMock that I was  
using for a while, but some recent refactoring removed all the tests  
that were using it. OBProtocolMockTest is a pretty good documentation  
on how to use it, for those who are interested.

In general though, I agree with Markus, Martin Fowler and others that  
excessive use of mocks leads to fragile tests. A few years ago,  
OmniBrowser had an extensive set of "behavior tests" involving lots  
of mocks. Then I made a small design change that completely broke all  
those tests. Dozens of them. I ended up just throwing away the tests  
and leaving parts of OB untested. Recently I've been rewriting those  
parts anyway, and slowly they're getting covered with tests again,  
this time without mocks.

These days, I find I use mocks very, very infrequently.  
OBProtocolMock was written for a fairly unique situation, where the  
functionality I was testing was a message dispatcher. It's job was to  
receive messages and forward them on to other objects according to  
certain policies. I used the protocol mock to verify that the right  
messages were being forwarded correctly.

Another area where I find that mocks are really handy is in testing  
input/output. I once implemented a MockWriteStream in VW that was  
very handy for testing code that wrote out data in specific file  
formats. For example, might write a test like this for an html  
serializer:

document := HtmlDocument title: 'Example'.
stream := MockWriteStream on: '<html><head><title>Example</title></ 
head></html>'.
document writeOn: stream.

If the document wrote everything out as expected, the test passed. If  
it wrote something incorrectly the mock stream would throw a  
TestFailure exception. It was great for debugging, because you could  
see exactly which code was writing the wrong thing.

In Squeak I once wrote a Mocket class which did the same sort of  
thing for sockets. Mocks are especially handy when testing network  
protocol implementations because they let you get around the  
threading issues that come up when testing real clients and servers  
together.

On the whole, I find mocks are very useful when the functionality I  
want to test is communication in some form or another. Most of the  
time, though, I don't care what messages are sent, since the result  
I'm after is usually some kind of state. Further, specifying the  
messages that have to be sent ties my hands when it comes to  
implementation, since messages are all I have to work with.

Colin




More information about the Squeak-dev mailing list