Akos Gyimesi wrote:
every function call has a
corresponding mock call in the test, so whenever you modify the
implementation (without even changing the top-level result) you have to
modify the tests as well, and vica-versa. I once encountered a codebase
that had thousands of lines of such "tests", and it was a nightmare to
modify anything in it.
That used to bother me too, until I had an Experience. It was a browser
front end written in, heaven help me, Objective-J. (Not -C. -J.
http://en.wikipedia.org/wiki/Objective-J)
Because I am lousy at GUI design, I at some point had to make a big
revision. I remember distinctly looking at a file of maybe 20 tests and
realizing I was going to have to rewrite them all. I was discouraged
until I suddenly realized that every one of those tests represented
something that had once been important about the UI. They could be seen
as a record of design choices/decisions. Some of them were relevant to
the new UI, and I ended up being glad I could look at each test and ask
myself "Self, what would be an analogous test for the new UI?"
http://atulgawande.com/book/the-checklist-manifesto/
Since then, modifying tests hasn't bothered me as much. (But note: if a
simple change means modifying a whole lot of tests, you're probably
doing something wrong.)
In fact, I sometimes point out that I've lived through the transition
from a time when almost all programmers scorned and despised writing
tests and the few who did were oddballs, to a time when writing tests is
- if not as common as NOT writing tests used to be - not at all oddball.
BUT the same programmers who love writing tests despise REwriting tests.
Except for a few oddballs. Like me. The vanguard of a new revolution!
Or perhaps not.
Maybe the "big trick" is to use the mocking features for unfinished code
(they are indeed convenient in Midje), but remove them immediately after
the lower-level components are implemented.
I believe some people do that. I don't. The main reason is that doing so
will very often require spending time setting up data. My coding is very
hashmap heavy. My test for a function will pass typically pass in a very
sparse map, containing only the keys referenced by that function. If I
now replace a call to a mock with a call to the real function (which
itself calls another real function, etc.), chances are I'll have to
construct a big old map like the ones that flow through it in production.
I have as strong an aversion to maintaining setup code as other people
have to maintaining mocking tests.
BTW my current approach is to test mostly without mocks, from as
high-level as reasonably possible:
- If possible, test a module from its public interface
- If this is too much pain (e.g. the execution has too many branches and
it is hard to exercise all of them), descend one level: take the
high-level components of the module and test these parts individually.
Descend another level if it's still too painful, (recurse). Always keep
a few integration tests that exercises the components together.
Interestingly (to me, at least), that's pretty much the approach I took
in my first book, /The Craft of Software Testing/, 1994. It took some
ferocious arguments on the C2 wiki around 2000 + buckling down and
really trying XP-style unit testing for a few thousand lines of Java to
change my mind. Then it took me many more years to finally figure out
what the London mocking people were talking about. (I was actually a
reviewer on the very first paper on mock objects, and I *completely*
missed the point. I apologized to Steve Freeman for that the first time
I met him, and he replied, "That's OK - everyone did.")
I don't claim my progression is inevitable for all Right-Thinking
People. I value some things more than other people, and I worry less
about some drawbacks than other people. Thus we might make different
choices.
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.