Jest: Как издеваться над компонентом экспорта по умолчанию, когда тот же модуль также назвал экспорт?
У меня есть модуль ES6, который по умолчанию экспортирует класс React Component, но также экспортирует простую JS-функцию как именованный экспорт. При тестировании других пакетов, которые используют этот модуль, я хочу высмеять как экспортированный по умолчанию компонент, так и названную экспортированную функцию, чтобы мои чистые тесты были чистыми.
Модуль выглядит примерно так:
import React, { Component } from 'react';
export default class MyComponent extends Component {
render() {
return <div>Hello</div>
}
}
export function myUtilityFunction() { return 'foo' };
Я хотел бы использовать следующий синтаксис для издевки экспорта:
import React from 'react';
import MyComponent, { myUtilityFunction } from './module';
jest.mock('./module');
MyComponent.mockImplementation(() => 'MockComponent');
myUtilityFunction.mockImplementation(() => 'foo');
Однако, когда я пытаюсь использовать этот синтаксис, MyComponent не выглядит издеваемым при использовании в других компонентах. Когда я пытаюсь издеваться над MyComponent как это и самостоятельно выносить его, он отображает значение null.
Такое поведение очень странно, потому что, если я использую тот же синтаксис, но оба импорта являются функциями JavaScript, насмешливые работы, как и ожидалось. См. Проблему StackOverflow, которую я открыл здесь, которая подтверждает, что синтаксис работает, когда импорт является обеими функциями.
Вот репозиторий GitHub, демонстрирующий проблему, а также несколько решений, которые я пробовал: https://github.com/zpalexander/jest-enzyme-problem
Вы можете построить репо и запустить тесты с помощью теста пряжи && пряжи
Спасибо!
Ответы
Ответ 1
Другое решение не сработало для меня. Вот как я это сделал:
jest.mock('./module', () => ({
__esModule: true,
myUtilityFunction: 'myUtilityFunction',
default: 'MyComponent'
}));
Другой способ сделать это:
jest.unmock('../src/dependency');
const myModule = require('../src/dependency');
myModule.utilityFunction = 'your mock'
Ответ 2
Я думаю, проблема заключается в том, что методу getElement класса ShallowWrapper необходимо передать класс, содержащий метод рендеринга. Для этого ваш MyComponent.mockImplementation должен более полно издеваться над конструктором класса.
Подробнее о том, как издеваться над конструктором класса, см. Документацию Jest, начиная с "mockImplementation", также можно использовать для моделирования конструкторов классов: https://facebook.github.io/jest/docs/en/mock-function-api. HTML # mockfnmockimplementationfn
Используя документацию Jest в качестве модели, мы можем высмеять конструктор класса MyComponent и сделать его мелким визуализируемым ферментом следующим образом:
MyComponent.mockImplementation(() => {
return {
render: () => <div>MockComponent</div>
};
});
Теперь, когда getElement ищет метод визуализации, он найдет его.
Вот суть, которая реализует это изменение в файле App.mockImplementation.test.js из вашего репо: https://gist.github.com/timothyjellison/a9c9c2fdfb0b30aab5698dd92e901b24