1. Mocks are great, we'll use them everywhere.
2. Mocks are preventing our tests from being refactored.
3. Mocks are preventing our code form being refactored.
4. Mocks are preventing progress on the platform.
5. Code is being modified and tests and mocks are being removed to keep productivity up.
6. There are no mocks and few tests.
7. Tests increase again as defects are found. No mocks required.
This is over the space of 8 years and our problem was the amount of coupling they caused.
Mocks, almost by their very nature, encourage coupling. Ask yourself the question "What tends to get mocked? " Answer: Objects which are difficult and/or heavy to instantiate, but which are outside of your direct control and cannot be changed, e.g.: database connections, network sockets, etc.
So when you want to write tests around this you are almost forced to mock them out. So you instantiate those classes (as mocks) in your test class, so that the code under test. There are now two references to that class: one in the test, and one in the code being tested.
This is coupling. QED.
Answer: every collaborator of the object under test, so that only the tested object is actually having its implementation exercised. All other objects that it needs to talk to — database connections, network sockets, or whatever — are replaced with mocks, and the test subject’s interactions with those mocks are verified, so that a) we have confidence that the tested object is interacting with its collaborators in the expected way, and b) the test itself doesn’t depend at all on the actual behaviour of those collaborators’ implementations, which behaviour should be explicitly exercised elsewhere.
That’s the opposite of coupling. I don’t understand where your answer comes from or what it means.
The issue is that you should want to make it very easy to change the API signature of internal components.
Mock objects can tend to reinforce internal coding choices when things that are not a public interface, or a service boundary, are mocked out.
If you're mocking at this level, there is a potential for refactoring of intra-class API contracts to become much harder to change.
Thus, it would be better IMHO to mock out only meaningful service boundaries, and concentrate testing at the public contracts.
You can still get very strong coverage, but you're just thinking about a different level of inputs.
Mocking and stunning in the manner you describe makes tests extremely dependent upon the current implementation. In fact, it inverts the relationship your tests should have with your development process.
Tests should allow you to refactor without breaking tests, and tests should break when APIs you call change in incompatible ways. These are the two primary long-term benefits that tests offer. Stubbing and mocking all of their internals causes tests to break when you change internal implementation (library Foo was switched to library Bar, but Foo is mocked and has a different API than Bar). It also causes tests not to break when the Foo API is incompatibly changed by another developer.
I really hope that you're not being serious here.
By this reasoning, the test suite itself causes coupling to increase. For any component C, you have at least N=2: when it's used in production code, and when it's tested. If you don't test C, you reduce N to 1. This doesn't sound like a good argument against testing, though.
I think there might be subtle differences is how we are mocking objects and how we organize our code that might make mocking have different outcomes. That's why I would like to see actual examples that can be deeply analyzed. I suspect that it's in fact the way the code is written and what the underlying platform allows that makes one more suitable than the other rather than mocks being fundamentally a poor choice.
An example of complicated mocking can be seen here:
https://github.com/openstack/nova/blob/master/nova/tests/vir...
In particular, SpawnTestCase.
Disclaimer: While I didn't write this example, I am responsible for some of the other mess