Brian Candler [mailto:B.Candler / pobox.com] wrote:

> I'd just create a class - see attached minor modification to 
> your example. It might not be any more concise but IMO it's 
> very clear (clearer than attaching methods to a vanilla 
> Object anyway), very flexible as you can expand the 
> capabilities of the mock object easily, and perhaps most 
> important, easily reusable as you add extra test methods.

Oh, I've created that class many times in the past... but I guess after
doing lots and lots of unit testing (and I have done LOTS and LOTS of unit
testing) I've come to find that, for me at least, it's often more useful to
start (and sometimes end) with a completely self-contained test method. Why?
Hmmm...

Well, for one, it cuts down on start-up overhead. I like to write a little
test, watch it fail, write a little code, watch it pass, write a little
test, ad infinitum. If my test method is self-contained when I start, I
don't have to spend precious brain cycles (and when you're working in 60-300
second cycles, seconds are important) figuring out what the name of the Mock
class should be, if it needs an initializer, where it should go, etc. I just
create an object, attach some methods, and pass it in. Easy, quick, concise,
to the point.

Another thing that factors in here is the issue of reuse in tests. I don't
aggressively remove duplication in tests like I do in code. My tests help
document the behavior of the system, and I want those tests to say a lot.
Too much reuse cuts down on how much an individual tests says. I have to
look here and find this mock object, and and here to find that one, and in
setup to see how they're initialized, etc. Instead I often find it's better
to keep my test methods small and decoupled, with each saying just what
needs to be said for that particular test - even if some of what they say
overlaps what another test says.

Plus, I just think it's nifty... I can show it to all my friends stuck in
Java land and say, "Can't do that in Java, can ya?" :-)

Now, I certainly pull things out in to setup, create classes just for
testing, and do various other types of reuse in my tests. Sometimes I wonder
if that means my tests (or the units they're testing) are too complex. Other
times I know that that complexity is necessary.

Anyhow, I don't think you'll convince me to stop doing this - and I'd
encourage you (and anyone else) to try it and see what it does to your
testing. There's an equilibrium between reuse in tests and expressing
everything in the test method. I'm sure that the right decision is different
for every test we write.


> You can pass in stuff to initialize of course, and accessors 
> to reset the object's "private" state seem reasonable enough to me.
> 
> If you are setting up local variables, binding them into 
> closures and then binding those closures to objects as method 
> definitions, then really those local variables are only there 
> to preserve state between calls of a method. In that case all 
> you've done is simulate an object's instance variables.

That's not why I want to do it, though; I find that a lot of times when I
have some values returned by a mock, I want to use those values in my
assertions on the class under test. So if I can bind closures as the methods
for my inline mock, I don't have to declare those values twice, or add a
mechanism to pass them in to the mock.

Thanks for your help,


Nathaniel

<:((><