Daniel Vartanov wrote:
Let's imagine, that we test a controller method - isolated peace of
code with a well-defined responsibility: treat request and produce
response (and may be also authorize user). We set up our mocks and
stubs, i.e. doing minimal setup for running single method.
And what we have? Test fails because view-file called methods of your
model, which you did not mocked or stubbed. So, we have to setup
UNNESSESARY stub-methods/mock-expectations because of code, which has
no meaning during the test. As a result, our nice simple test code
grows up to a unreadable monster.
Does anyone have experience with solving this problem?
You have way too many mocks. The "minimal setup" rule does not mean "set as few
of your real objects up as possible".
It means that the fewer mocks you must use, and the fewer objects you must setup
to test something, the more clean, lean, and decoupled your code is. Expensive
setup is a design smell, and mocks are _more_ expensive than production objects.
All your objects should be ready to work in a minimal state without extra work
to set them up.
You should only mock expensive things, such as hardware, random numbers, the
system clock, etc.
Leave your mocks in this test, and (if you use Mocha) use Mocha's any_instance
to whack the model methods you can't bear to call. Then, in your next test, turn
on the fixtures you need to truly test, and call everything without any mocks.
TDD is not "unit testing", which is a Quality Control concept of
mission-critical applications. TDD is about serendipitous cross-testing of many
features out of each test case. Unit tests with overlapping units are bad; TDD
with overlapping units is good.