Unit testing will inherently nudge you towards writing your code in a maintainable way. You’ll separate concerns, design sensible interfaces, and break your code up into small, easy-to-reason-about chunks.
Modern language features like async / await and functional reactive programming bring incredible ergonomics to our code, however your tests for this code can be flakey if you’re not careful.
I’ve always wanted to write this one, since I rarely see it explained well - frankly, it’s a tough set of concepts, and clearly I think a lot of myself if I’m writing a 6-part series:
Part II Mocking like a Pro
Part III Unit Testing with async/await
Part V (interlude) — Implement your Data Access layer with Combine
Part VI Combine, async/await, and Unit Testing
Part I - Dependency Injection
Dependency injection, a.k.a. DI, is a handy concept that’s often explained terribly. So-called “senior devs” (i.e. nerds) invoke cryptic jargon like inversion of control, and parrot unhelpful platitudes like DI is a 25-dollar term for a 5-cent concept.
I viscerally remember these exact phrases making me feel like both an idiot and an imposter when I was a junior. Hell, maybe when I was a mid.
What is DI?
I was fortunate enough to marry this year, and duly abandoned my obligation to stay in shape - so I’ll indulge in a culinary analogy.
Think of DI like a fancy restaurant. Your class (or struct, module, etc.) is head chef, and DI is the sous-chef who hands her the ingredients she need to cook up a storm. By separating the tasks of "gathering ingredients" and "cooking," our menu is far more testable (I never said the analogy would make sense).
Without dependency injection here, we’d force the chef to make up the ingredients herself, rush to cook, and leave us with an unmaintainable dumpster fire of a kitchen.
In a nutshell, DI divides the duties of “get what I need” and “do what I need to do” like a perfectly sharpened cleaver. Bon appétit!
What does this have to do with testing?
Hold your horses!
I could dive right into testing, and tech you how to write basic tests to prove that 1+1= 2, or that the string you hardcoded matches… well, your hardcoded string.
I’m starting slow and steady with DI because I want to give you a proper foundation to start from.
Essentially, what I’m saying is, you don’t want to brush your teeth (unit test) until after you’ve eaten your veggies (created mocks); and you need to preheat the oven (learn dependency injection) before you can cook your veggies.
When you use DI to inject services into your classes, you can create a corresponding buffet of mock services. These conform to the same interface - they look and act like the real deal - but really it’s you pulling the strings.
This is where the magic happens:
With your mock, you can count how many times the mock’s functions are called, stub out test data to return, or even make it scream
ERROR!in digital agony. This control allows you to write test cases for every conceivable outcome.You’ll get a much more in-depth explanation, along with worked examples, in Part II: Mocking like a Pro and Part III: Unit testing async code - the basics.
Worked example: Bev app
Here’s some sample code I whipped up for an app called Bev, which uses the fantastic PunkAPI to get data on Brewdog beers. It’ll be our gourmet code reference throughout this series.
Bev app and architecture and data flow
The structure is a basic layered modular architecture, (wildly overkill for a project this size, but perfect for future blog topics).
The key layers in our technological lasagna are:
UI / Presentation Layer - display UI + handle events (such as user actions)
Data Access Layer - defines “what” data we want to get
Network Layer - deals with “how” we get this data

Each layer depends on the layer underneath: With DI, we can serve our class up something to allow smooth communication between the layers.
As well as nicely separating your concerns, this technique is extremely important when it comes to testing your code - wait for Part II: Mocking like a Pro to see how.
I’ve waffled for long enough. It’s time to show you some code.




