Как вы вручную издеваетесь над своими файлами в Jest? - программирование

Как вы вручную издеваетесь над своими файлами в 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 - пустой метод, который ничего не делает, что означает тест терпит неудачу.

Любые идеи, что я делаю неправильно?

Спасибо большое

4b9b3361

Ответ 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`
))