Most of the systems I build use a database on which all logic depends, and often a network connection.
I've worked on systems where these aspects were mocked, and they eventually grind to a halt because of the effort required to make the tiniest change.
First of all you need a way to create a pristine database from code, preferably in memory. Second nested nested transactions are nice, since you can simply rollback the outer transaction per test case; otherwise you need to drop/create the database which is slower.
For networked servers, an easy way to start/stop servers in code and send requests to them is all you need.
Given these pieces, it's easy to write integration tests that run fast enough and give a lot of bang for the buck.
TDD is even more rare for me, I typically only do that when designing API's I'm unsure about, which makes imagining user code difficult. And fixing bugs, because it makes total sense to have a failing test to verify that you fixed it, and that it remains fixed.