In the intervening months between the problems of The Second Time I tried TDD and when I actually embraced it as a viable software creation methodology, I would use it for small components, or for parts of the system that had no external interfaces (think Third-party HTTP API endpoints, Database, or the UI), but I would avoid using it in cases where I needed to integrate with a third party API. The mechanics of Mocking and Stubbing (especially Mocking) felt unstable. Unhelpfully the “Mockist” TDD mindset was “if you’re having a problem mocking or stubbing, it must be you,” and the “classicists” had already cast aside mocking and stubbing.
If you’re me, you’re wondering who the heck all these people are and why their battles feel like a religious war (and programming has enough of those already). Let’s ignore them for now and move backwards *slowly* towards the car. So there I was, lamenting the fact that I couldn’t resolve the words spoken by TDD’ers (You can write your whole appliction using TDD!, or “You’re not professional if you don’t use TDD!”) and the pain I felt trying to do so. And then I had the good fortune to attend PyCon 2013 (The company I was a part of at the time had an amazing conference budget – basically you could spend 2500 a year on conference attendance, few to no questions asked) and I was able to watch Gary Bernhardt’s Boundaries talk, live.
Gary’s talk has a simple concept behind it: Push all of your core decision making code into a functional-style that works with POCOs or the language’s primitives. The code that has to talk to the outside world is your ‘shell’, and that can be written in an imperative style; with all of the modern day associations we make (like third party HTTP APIs, Database calls, and the UI).
This talk changed everything for me. Patterns that I had been trying to implement but partially failing now made sense as to why. The problem of mocks and stubs started to fade away, and I realized I could use TDD to build an entire application — or at least everything inside of the boundaries. It was then that Test Driven Development started to change for me. It was then I felt the logjam break.
I’ve been using this approach since 2013 to build applications, and I’ve learned quite a bit along the way. My course, Test Driven Development for .NET Project Software Teams shows you how to implement the “Functional Core, Imperative Shell” style in .NET applications, as well as teaches the architectural and practical issues you’ll come across and how to make it so you really can deliver better software, faster, through TDD. If you’re interested, sign up to hear about course progress and to get a special subscriber’s discount no one else will receive.