DEV Community

Discussion on: Why Mocks Are Considered Harmful

Collapse
 
joelbonetr profile image
JoelBonetR 🥇 • Edited

The reason behind mocks is not to enable tests in an early stage but decoupling the dependencies from back to front teams conceptually.

They have nothing to do with unit tests (they validate that a function returns the expected from a given input. Good tests do that multiple times with different inputs to validate every possible situation).
They also have nothing to do with end to end tests (by definition, they need to be done AFTER the integration).

1

Let's say a backend team estimate tasks for a week, frontend estimate theirs for another week. The delivery would be in 2 weeks then.

2

Instead, both teams agree on a model, schema, structure or response, they mock it as the contract and they use it to perform further developments till both parts are finished (and unit tested... hopefully).

This work about defining needs that leads to a contract will be needed anyway so no time wasted here. The mock can be also auto-generated from the contract, so again, no time wasted here.

We've just used a week at this point, then you just need -let's say- +1 day to integrate (usually less).

3

Integration process begins, if the backend and frontend implementations are correct from the contract point of view it will be OK at the first try, otherwise one team or another will need to perform further changes to adapt it, which is the reason for estimate integrations according to the model complexity.

Note that we reduced the delivery time of that [feature or whatever] by 4 labour days by using mocks.

4

Once it's finished QA team will apply integration tests, also called End to End (which are by no means replaceable by unit tests) and which are not -usually- a developer responsibility.



The main reasons for using mocks are:
  • Clients can't understand why both teams can't work in parallel to solve their need of having the features on a given deadline because investors are pushing on them as well.
  • It's quite hard to sync back and front to have things to do if a team is waiting the other fo finish things (blockers) and the people paying you don't like that either, for obvious reasons.

Nothing more, nothing less. It's convenience.



On the other hand I don't really know how you plan to call my "pure functions" or "methods" when they are private to their context.
import { schema } from 'whatever';

// non callable from outside this context
const validateInput = (input) => schema.validate(input).then( x => JSON.parse(x));

// what unit test actually will test
export default function doSomething(input) {
  const validation = validateInput(input);
  if( validation.error ) return;

  // also non callable from outside this context
  const doMagic = (data) => {
     return data.specs;
  }

  const result = doMagic(validation);
  return JSON.stringify(result);
}
Enter fullscreen mode Exit fullscreen mode

Do you plan to export every single function so you can test them individually? That's ridiculous!


Other reasons for using mocks:

  • Mocks can either be deleted once the integration is done or stored within a tool to see diferences on them for future updates, they are a good place to quick search when a change was made so you can check the email to see the client request 😂

  • They are also good when doing PoCs, because usually the user will require changes on them before they qualify as "valid" to start developing over them. If you code in real the DB model/schema, migrations, validations, CRUD functions etc, when the customer requires a change you'll need to edit all those steps instead a single mock, which is clearly a lose of time (and more times that what we would like to admit, garbage will be left in the code from those changes).

  • The tests performed on functions that use mocks will also work after the integration. If a test fails after the integration step chances are that the issue is either due to a contract break by one of the teams or in the data (or lack of it) and is usually the first thing to look at after the contract-implementation double-check.




TLDR;
  • The industry won't stop using mocks and there are good reasons for that.
  • No one consider mocks harmful.
Collapse
 
starkraving profile image
Mike Ritchie

This is exactly the use case I like, thanks for saving me from having to write a response of my own! The other modifications to this use case is to allow the stakeholders access to the frontend early, for feedback and refinement. The mock you use in this case becomes the basis for the data contract that the backend team uses later to complete the API. This allows the finished product to be as closely aligned as possible to the stakeholders’ needs quickly, and with effort limited only to the frontend.