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.