From: Nathaniel Talbott Date: 2003-08-03T00:32:08+09:00 Subject: Re: Anonymous, single instance class creation 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 <:((><