Also, with Docker it's now actually feasible to automatically test against a real database at a reasonable speed. A Postgres container spins up in a couple of seconds, a SQL Server one in a little over four.
But you can of course achieve the same by running a script before your tests start. There are also some frameworks for doing this sort of thing too, such as Fixie for .NET
There are also other scenarios that become really simple with disposable DB instances. Want to test a remote data transfer feature? Just spin up two databases.
Namely a context like travis-ci where you get a new clean environment each time.
Personally, I've develop few libraries/web UIs that relies on external software like a DNS server or an ldap directory.
And for those, I've a quick and dirty shell script that deploys bind/OpenLDAP.
It's far easier, faster and more accurate than mocking.
For example, what comes to my mind is the testing I do for all the SSL/TLS modes I support (SSL, StartTLS, certificate check disable or not, etc) in my ldap web application.
Travis also has available services in their build envs (stuff like redis, mongodb, mysql, cassandra...).
I've seen what happens when a developer tries to abstract away a database in a database driven app so it can be "better unit tested". It's a goddamn mess.
If your app relies heavily on using a database, your app naturally integrates with a database then it makes no sense to test without it. You are intentionally avoiding testing in a way that will pick up bugs.
>Unit tests run faster, are written faster
Unit tests test less realistically. That means they don't catch bugs integration tests do.
They also often take longer to write and are more tightly coupled.
How coding this way came to be seen as a best practice is beyond me. Tight coupling and premature optimization is usually seen as bad practice in other areas.