Jest: Используйте mock модуля только для CI и локально используйте оригинальную реализацию - PullRequest
0 голосов
/ 25 сентября 2019

Я пишу библиотеку Bluetooth , и я тестирую ее с помощью Jest.Для своих тестов я делаю реальную радиосвязь, чтобы убедиться, что все действительно работает.Однако такого рода тесты нельзя запускать в системе CI.Поэтому для моей системы CI и только для моей системы CI я хочу использовать макет.Что касается локальной разработки, я не хочу что-либо издеваться.

Поэтому я попытался условно насмехаться над модулем в jest:

import MyModule from "./myModule";

if (true) {
  jest.mock("./myModule");
}

describe("MyModule", () => {
  let myModule;

  beforeEach(() => {
    myModule = new MyModule();
  });

  test("I am NOT mocked", () => {
    expect(myModule.powerOn()).toBe("I am the original implementation");
  });

  test("I am mocked", () => {
    if (myModule.powerOn.mockReturnValueOnce)
      myModule.powerOn.mockReturnValueOnce("I am a mock");
    expect(myModule.powerOn()).toBe("I am a mock");
  });
});

, но это не работает.Результаты моего теста

 FAIL  ./index.test.js
  MyModule
    ✓ I am NOT mocked (3ms)
    ✕ I am mocked (6ms)

  ● MyModule › I am mocked

    expect(received).toBe(expected) // Object.is equality

    Expected: "I am a mock"
    Received: "I am the original implementation"

      19 |     if (myModule.powerOn.mockReturnValueOnce)
      20 |       myModule.powerOn.mockReturnValueOnce("I am a mock");
    > 21 |     expect(myModule.powerOn()).toBe("I am a mock");
         |                                ^
      22 |   });
      23 | });
      24 | 

      at Object.toBe (index.test.js:21:32)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 passed, 2 total
Snapshots:   0 total

Как только я удаляю предложение if

if (true) {
  jest.mock("./myModule");
}

до

jest.mock("./myModule");

, оно работает как ожидалось.

Вы можете попробовать это здесь

https://github.com/LukasBombach/jest-conditionally-mock-module-example

Я не могу поместить его в CodeSanbox, потому что этот код нарушает его.

У меня естьпрочитайте, что jest должен иметь mock для модуля в корневой области вашего файла, потому что он анализирует ваш файл перед тем, как его запустить, и выполняет с ним какую-то магию. Я знаю это .

Но так как кажется, что невозможно поместить jest.mock в предложение if, есть ли другой способ заставить мой CI использовать макет и локальноработать с моей реальной реализацией?

1 Ответ

0 голосов
/ 25 сентября 2019

Хорошо, я нашел решение сам. С этим вопросом связан , но я нашел другое решение, которое мне нравится больше.Вы можете использовать второй параметр (заводской), чтобы решить, хотите ли вы вернуть макет или фактический модуль

Убедитесь сами

import MyModule from "./myModule";

jest.mock("./myModule", () => {
  if (false) return jest.requireActual("./myModule");
  return jest.genMockFromModule("./myModule");
});

describe("MyModule", () => {
  const myModule = new MyModule();

  test("I am the original", () => {
    expect(myModule.powerOn()).toBe("I am the original implementation");
  });

  test("I am mocked", () => {
    myModule.powerOn.mockReturnValueOnce("I am a mock");
    expect(myModule.powerOn()).toBe("I am a mock");
  });
});
...