mardi 30 octobre 2018

How do we mock out dependencies with Jest _per test_?

(Here's the full minimal repro: https://github.com/magicmark/jest_question)

Given the following app:

src/food.js

const Food = {
  carbs: "rice",
  veg: "green beans",
  type: "dinner"
};

export default Food;

src/food.js

import Food from "./food";

function formatMeal() {
  const { carbs, veg, type } = Food;

  if (type === "dinner") {
    return `Good evening. Dinner is ${veg} and ${carbs}. Yum!`;
  } else if (type === "breakfast") {
    return `Good morning. Breakfast is ${veg} and ${carbs}. Yum!`;
  } else {
    return "No soup for you!";
  }
}

export default function getMeal() {
  const meal = formatMeal();

  return meal;
}

I have the following test:

__tests__/meal_test.js

import getMeal from "../src/meal";

describe("meal tests", () => {
  beforeEach(() => {
    jest.resetModules();
  });

  it("should print dinner", () => {
    expect(getMeal()).toBe(
      "Good evening. Dinner is green beans and rice. Yum!"
    );
  });

  it("should print breakfast (mocked)", () => {
    jest.doMock("../src/food", () => ({
      type: "breakfast",
      veg: "avocado",
      carbs: "toast"
    }));

    // prints out the newly mocked food!
    console.log(require("../src/food"));

    // ...but we didn't mock it in time, so this fails!
    expect(getMeal()).toBe("Good morning. Dinner is avocado and toast. Yum!");
  });
});

How do I correctly mock out Food per test? I don't want to override Food for every test case, just for a single test.

I would also like to not change the application source code ideally (although maybe having Food be a function that returns an object instead would be acceptable - still can't get that to work either tho.)

Things I've tried already:

  • thread the Food object around through getMeal + use dependency injection into formatMeal
    • (the whole point of this approach IRL is that we don't want to thread Food around the whole app)
  • manual mock + jest.mock() - it's possible the answer is here somewhere, but it's tough to control the value here and reset it per test due to import time weirdness

Thanks!

Aucun commentaire:

Enregistrer un commentaire