Microservices and Outside-in Tests Using C# and Docker Compose

Andrew Craven
7 min readDec 23, 2019

Is This For Me?

I’m going to showcase how I prefer to structure my microservice repositories while I practice Outside-in TDD using C# and Docker Compose.

I’ll show you how I create the skeleton repository with some initial tests. We will implement some temporary behaviour to satisfy the tests before replacing it with a more persistent solution.

If you’re like me, you won’t have Christmas done, so we will walk through the commits in the repository to save a bit of your time. What you gain from not copying and pasting, can be spent on wrapping and sticking instead!

This post is one of a series that is the The 3rd Annual C# Advent. Please take a look at the other posts and perhaps get your thinking caps on for the 4th.


A number of years ago I was working for a client that decided we should be favouring outside-in tests. I understood the term to mean that tests shouldn’t have any knowledge of the inner workings of a component, but instead should just validate any outputs and/or any side-effects.

What I’ve learnt whilst applying this approach with other clients, is that it’s only half an understanding; when you realise the tests you WERE writing, were inside-out, things finally click. These tests may well have had no knowledge of the inner workings of the component they were testing etc. etc., but we were in fact solving the problem from the inside-out rather than outside-in.

Typically inside-out TDD will focus on teasing out detail in small components, and as a developer you will work towards the outside, layering more components until you get to the exposed surface of the API. These tests will be coupled to the implementation of your components and may prove costly during future maintenance. Conversely, with outside-in TDD you will construct tests that interact with the surface of the API only, without delving into implementation details.

The advent (excuse the pun) of containerisation has certainly helped in my understanding. Being able to replace whole components, or indeed containers without needing to refactor a whole heap of tests is a very compelling argument.

Andrew Craven

Freelance Engineer, Architect, Problem Solver etc. https://twitter.com/acraven_dev