Как вы вручную издеваетесь над своими файлами в Jest?
Я пытаюсь высмеять объект (который я создал) в Jest, чтобы я мог обеспечить поведение по умолчанию в реагирующем компоненте (поэтому реальная реализация не используется)
Это мой реактивный компонент ChatApp (он очень прямой)
'use strict';
var React, ChatApp, ChatPanel, i18n;
React = require('react');
ChatPanel = require('./chat_panel');
i18n = require('../support/i18n');
ChatApp = React.createClass({
render() {
return (
<div className="chat-app">
<h1>{i18n.t("app.title")}</h1>
<ChatPanel />
</div>
);
}
});
module.exports = ChatApp;
Итак, у меня есть пользовательская зависимость I18n, которая выполняет переводы (I18n - это то, что я написал, это оболочка для node -polyglot).
Итак, я хочу сделать базовый тест, чтобы увидеть, имеет ли H1 правильное слово в нем, но я не хочу устанавливать jest.dontMock() на свой объект I18n, потому что я не хочу, чтобы он использовался реальный объект в тесте ChatApp.
Итак, следуя основным инструкциям на веб-сайте jest, я создал папку mocks и создал файл mock для i18n, который генерирует макет из исходного объекта и затем переопределяет метод t и добавляет метод, позволяющий мне установить возвращаемую строку для t.
Это макет объекта
'use strict';
var i18nMock, _returnString;
i18nMock = jest.genMockFromModule('../scripts/support/i18n');
_returnString = "";
function __setReturnString(string) {
_returnString = string;
}
function t(key, options = null) {
return _returnString;
}
i18nMock.t.mockImplementation(t);
i18nMock.__setReturnString = __setReturnString;
module.exports = i18nMock;
Теперь в моем тесте ChatApp мне требуется mock в перед каждым, например:
'use strict';
var React, ChatApp, TestUtils, path;
path = '../../../scripts/components/';
jest.dontMock( path + 'chat_app');
React = require('react/addons');
ChatApp = require( path + 'chat_app');
TestUtils = React.addons.TestUtils;
describe('ChatApp', () => {
beforeEach(() => {
require('i18n').__setReturnString('Chat App');
});
var ChatAppElement = TestUtils.renderIntoDocument(<ChatApp />);
it('renders a title on the page', () => {
var title = TestUtils.findRenderedDOMComponentWithTag(ChatAppElement, 'h1');
expect(title.tagName).toEqual('H1');
expect(title.props.children).toEqual('Chat App');
});
});
Если я console.log объект i18n в тесте, то я получаю правильный издеваемый объект, также запускается __setReturnString (как если бы я console.log в этом сообщении я вижу в журнале).
Однако, если я console.log объект i18n в действительном компоненте React, тогда он получает макет Jest, но он не получает мой Jest mock, поэтому метод t - пустой метод, который ничего не делает, что означает тест терпит неудачу.
Любые идеи, что я делаю неправильно?
Спасибо большое
Ответы
Ответ 1
У меня возникла проблема с работой папки __mocks__
. Способ, которым я обходился, - это использовать метод jest.setMock();
.
В вашем случае вы бы jest.setMock('../../../scripts/i18n/', require('../__mocks__/i18n');
Очевидно, что я не уверен в местоположении вашего макета и местоположении реальной библиотеки, которую вы используете, но первый параметр должен использовать путь, в котором хранится ваш реальный модуль, а второй должен использовать путь, mock сохраняется.
Это должно заставить ваш модуль и все модули, которые вам необходимы (в том числе React), использовать ваш ручной модуль i18n.
Ответ 2
Jest делает автоматическое издевательство. Просто i18n = require('../support/i18n')
должно быть достаточно. Вот почему вы обычно должны называть jest.dontMock
в первую очередь.
Вы можете найти более подробную информацию здесь: https://facebook.github.io/jest/docs/automatic-mocking.html
Ответ 3
Что mattykuzyk упоминает в его ответ, для меня не работает: (
Однако то, что я узнал, казалось, было проблемой для меня, была установка шутки: я использовал moduleNameMapper
в начале, и по какой-то причине они никогда не издеваются...
Итак, для меня первым шагом было вместо этого переместить мою сопоставленную папку с именем модуля в moduleDirectories
, чтобы заставить что-нибудь работать.
После этого я мог просто добавить файл __mocks__
рядом с фактической реализацией (в моем случае utils/translation.js
и utils/__mocks__/translation.js
).
Поскольку мой translations.js
по умолчанию экспортирует функцию перевода, я также по умолчанию экспортировал свой макет. Весь __mocks__/translations.js
супер просто и выглядит следующим образом:
export default jest.fn((key, unwrap = false) => (
unwrap && `${key}-unwrapped` || `${key}-wrapped`
))