CodePark/ questions / Unit testing services
START PRACTICINGPRACTICE
Backend question · Backend testing › Unit testing services

What is the difference between the classical (Detroit) and mockist (London) styles of unit testing? Which would you use for NestJS services?

The two styles differ in what a "unit" is and in what the test checks. For NestJS services I lean towards the classical style.

Classical (Detroit) style: a unit is a behaviour. One behaviour may use several real objects.

  • You use real collaborators (the other objects your code works with) when they are fast and deterministic. Deterministic means they give the same result every time.
  • You replace only the awkward ones, such as the database, the clock or an external API.
  • Tests check state: the returned value, or what ended up in a fake repository.

Mockist (London) style: a unit is one class, and every collaborator is a mock.

  • Tests check interactions: which methods were called, with which arguments.
  • It supports outside-in design, where you start from the outer layer and design inwards.
  • But it ties tests to how the class talks to its collaborators. So refactoring breaks the tests, even when the behaviour stays the same.

For Nest services I use:

  • real domain helpers;
  • test doubles only at process boundaries, such as repositories, HTTP clients and queues;
  • assertions on outcomes.

I check an interaction only when the interaction is the outcome, for example "an email was sent".

  • In the classical style, a unit is a behaviour, collaborators are real, and tests check state.
  • In the mockist style, a unit is one class, all collaborators are mocked, and tests check interactions.
  • Mockist tests break more often when you refactor.
  • Check interactions only when the interaction is the visible outcome.