You should have continued. His point is that while TDD is good for some things it misses huge areas and has very little ROI in most simplistic cases.
Yes, you can mock HTTP requests, but there are numerous bugs you wouldn't catch unless you went and hit your application with an actual browser. Similarly, you can mock the database, but you're not testing all the "magic" the database does and all the myriad combinations it could fail.
For those cases, tests have value in telling you where the bug isn't.
For me, one of the biggest benefits of code that has been written to be testable is that it's been designed such that it's possible to reason about fine-grained details. If I find a problem, I can generally start adding tests as part of the debugging procedure to make assertions about the specific part of the code that I think might be failing.
That's much harder to do at a sufficiently high level of detail if the code wasn't structured to make it easy from the start.
> Similarly, you can mock the database, but you're not testing all the "magic" the database does and all the myriad combinations it could fail.
You are correct. And this is why you unit test the DB and all the stored procs and queries you perform there.
And, this is also why you can add in tests that do use the database connection, and test the more complete stack. TDD does not limit you to only use the tests at the application level. It does not limit you to building other forms of tests. To imply that is dishonest. It would be akin to me saying "Because you do not use TDD, you do not test."
I have no intention of ever mocking the database, and I mock HTTP requests solely so I can work on my app without an internet connection. Look, a better approach is to use TDD for things it makes sense for. Spending a ton of time to mock out your database does nothing for you. Is mysql going to fail for you? Is the mysql driver that a million people are using going to fail for you? No? So, don't mock it out.
You don't mock the drivers.. you abstract the database layer to test for a particular data. For instance, you make getName() returns empty string, 1000 wide character string, strings with unicode, etc. It's not about MySQL; it's about what mysql returns.
Let's say you have a class that writes a string to the database. You abstract out the actual writing to the database of this string thinking it's always going to work, it's just dumping data after all. Your test passes, everything is good.
Now you optimize your database and add a restriction to make the string at most 50 characters. Your test still passes, but you now have a bug. OK, so you should've had a restriction in your BO. You add that restriction and move on.
Your DBA comes along and adds an integrity check or a trigger that makes the insertion fail if some weird condition is met. Your test passes, but you have a bug.
This can get even more interesting when you hit some basic database rule that you didn't even know it existed. You assume the insertion will work, but it won't. You now have a bug.
You've tested that 2 + 2 = 4, and it works, but when that code is linked with the actual database you realize that in some cases 2 + 2 doesn't equal 4.
I'm not saying don't have unit tests, but when it comes to bugs, the fast majority of these bugs, in my experience, come from the glue, from the assumption that the piece you're integrating with should work one way, but reality begs to differ.
Yes, you can mock HTTP requests, but there are numerous bugs you wouldn't catch unless you went and hit your application with an actual browser. Similarly, you can mock the database, but you're not testing all the "magic" the database does and all the myriad combinations it could fail.