Vincent A Saulys' Blog
Mocks, Spies, & Stubs in Jest & NodeJS
Tags: javascript
July 28, 2021

Martin Fowler, one of the godfathers of Test-Driven-Design (TDD), has written that mocks aren't stubs, which aren't spies.

This has always felt like a bit of nitpicking. I'm not sure knowing the specific difference helps when communicating with other people.

The Relevant Quote:

(emphasises are added for readability)

I have never in my professional experience heard people make a big difference between these types.

To add fuel to this, Facebook's Jest library doesn't differentiate between the two. The relevant quote below:

Mock functions are also known as "spies", because they let you spy on the behavior of a function that is called indirectly by some other code, rather than only testing the output.

Does any of this matter? or is it consultancy speak?

With regards to Facebook's Jest, I end up using the mocks by storing them into a __mocks__ library and explicitly ask Jest to mock it when calling a route.

Example is below:

// ./models/__mocks__/index.js
const models = jest.genMockFromModule("../");

models.thing = {
  findByPk: jest.fn(async () => ({
    name: "love"
  })),
  weirdFunc: jest.fn(() => 42)
};

module.exports = models;
// ./routes/__tests__/app.spec.js
const request = require("supertest");

const app = require("../../app");

jest.mock("../../models");
/*
  Because we're mocking this explicitly, we'll pull from 
  `../../models/__mocks__/index.js` and _not_ from the actualy model
 object

 Every other call to this object anywhere else in the code will now be
 mocked though I explicity check it here
 */

const { thing } = require("../../models");

describe("test", () => {
  it("works", async () => {
    expect(true).toBe(true);
    return;
  });

  it("should give me mocked models", async () => {
    // const _thing = await thing.findByPk(1);
    // console.log(_thing);
    expect(thing.weirdFunc._isMockFunction).toBeTruthy();

    const _thing = await thing.findByPk(1);
    // ... the rest of my test
    return;
  });
});

Share On:
DiasporaTwitterFacebookLinkedInHackerNewsEmailReddit