This exponential madness really irks me. I confess I have no idea how
you can even imagine something like that, especially considering you
test "in isolation". When you test A, B, and C three times each,
you've got 9 tests. And since you were careful to test them
in
isolation, you can be sure testing A doesn't miraculously test C as
well. Your 3^3=17 exponent comes out of nowhere.
Me on the other hand could pretend something to this effect. By testing
A, B, and C three times each, I effectively test B 6 times, and C 9
times, for a total of 3+6+9=18 "tests". But even then I would
hesitate to pull such a number out of my ass, because the extra "free"
tests are likely redundant with the real ones down the line. (And if
my coverage is any good, those are guaranteed to be redundant).
Surely you don't pretend mocking lets you test more things than my
approach? Surely the mocs don't behave any differently than the real
thing on the inputs they are given? How come then that my
"integration" tests don't supersede your unit tests?
> Choosing to write unit tests instead of integration tests does not
preclude the use of property based testing
I assume at this point that your definition of unit test means mocking
everything, except perhaps the standard library. You said earlier:
> Mocks verify that they were called in an expected way/order and
give back the appropriate value. They don't actually do
anything. They're highly coupled with each test case.
So, if tests are generated randomly, mocs must be adapted to each
random test, right? Now you need some moc generator, that will
generate a moc for each test case. This veers eerily close to
actually implementing the interface we were trying to moc.
Now I realise I did miss something:
> Mocks verify that they were called in an expected way/order and
give back the appropriate value.
Why would they do that? Oh, I see: we are mocking a mutable object
that is used somewhere else. In other words, shared state. The one
case for which I understand isolation could be good.
This may all be a big misunderstanding. The A->B->C dependency I was
thinking of is pretty simple: C is an implementation detail of B.
Each B contains and uses a C, but that C isn't used anywhere else.
Thus, mocking B or C would mean testing the implementation details of
A, and that is a big no-no —the kind of thing Uncle Bob would call TDD
gone wrong.
> And there really is a ton of value in testing code you've written
in isolation.
What value exactly? Does isolating objects in the tests make those
tests catch more bugs? What kind of bugs? Does isolating objects
make detected bugs faster to track down? Does isolating objects in the
tests influence how the code is written in the first place? How? Would
the test suite run faster?
> And yet the testing strategy you described is the opposite...trying
to test everything at once rather than focusing on each test
covering one specific bit of code.
Now that's a strawman. I don't test everything at once. If I did, I
would merely test A. No no no, I test and debug C first. When I'm
confident it is bug-free, I test and debug B. Bugs are easily tracked
down, because C is bug free, so if something went wrong it must be B.
I only test A last, when I'm confident B and C are both bug-free.