Jest макет импорта из файла утилиты - PullRequest
0 голосов
/ 01 мая 2020

Я пытаюсь стандартизировать способ, которым регулярно смоделированные функции подвергаются насмешкам.

Итак, у меня есть функция, которая обрабатывает вызов контекста домашнего экрана в useHomeScreenContext.ts.

export const useHomeScreenContext = () => useContext(/* context here */)

Затем компонент, который я тестирую, использует этот хук Component.tsx

export const Component = () => {
    const context = useHomeScreenContext();
}

Тогда мой тестовый файл для компонента выглядит так: Component.test.tsx

const contextSpy = jest.spyOn(context, 'useHomeScreenContext');
it("works", () => {
    contextSpy.mockReturnValue(fakeValue)
    expect(fakeValue).toBeTruthy()
})

Проблема, с которой я столкнулся при таком подходе в том, что будет большое количество файлов, которые нужно будет протестировать с помощью насмешек этого контекста, и фактическая имитация немного сложнее, чем я здесь изложил. Поэтому я хотел бы стандартизировать макет с помощью служебной функции, поэтому я создал отдельный файл с именем mockHomeScreenContext.ts, который выглядит примерно так:

const contextSpy = jest.spyOn(context, 'useHomeScreenContext');
export const mockHomeScreenContext = (context) => {
  beforeAll(() => {
    contextSpy.mockReturnValue(mergeDeepLeft(context, homeScreenContextDefaults));
  });

  afterAll(() => {
    contextSpy.mockRestore();
  });
};

С такой идеей, что он используется внутри блока описания, и он будет приводить себя в порядок в конце блока описания следующим образом:

describe('and does not have funds', () => {
    mockHomeScreenContext(contextOverrides);
    it("works", () => {
        // Tests here
    })
});

И это, кажется, работает очень хорошо, пока у меня не будет 2 блока описания, а затем все начнется на go немного ненадежно, и некоторые тесты, похоже, корректно воспроизводят данные, но тогда все последующие тесты не пройдут, так как фиктивная функция ничего не возвращает. Избавление от вызова afterAll для очистки макета помогает, но затем заражает другие тесты.

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

1 Ответ

0 голосов
/ 02 мая 2020

Я думаю, что проблема в том, что ваш contextSpy является глобальным для всех тестов, потому что он создан вне функции mockHomeScreenContext. Как вы можете найти в документации , mockRestore будет restore the original (non-mocked) implementation. Вместо этого вы можете попытаться использовать mockClear, так как это более мягкая версия (я обычно просто использую это).

Однако я бы предложил не издеваться над вашим контекстом, а создать провайдера, который будет заставить context работать должным образом, без необходимости делать обширные насмешки (что, как вы, вероятно, видите, может быть qu ie болезненным).

Вот пример того, что я имею в виду:

Использование в тесте:

<MockProvider context={contextOverrides}>
  <YourComponent/>
</MockProvider>

И реализация:

const MockProvider = ({context, children}) => {
  return (
    <YourContext.Provider value={mergeDeepLeft(context, homeScreenContextDefaults)}>
      {children}
    </YourContext.Provider>
  )
} 

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...