2015-02-14 3 views
12

Я пытаюсь издеваться над объектом (который я создал) в 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 является то, что я написал, что это оболочка для узла-полиглот).

Так что я хочу сделать базовый тест, чтобы узнать, имеет ли в нем правильное слово H1, но я не хочу устанавливать jest.dontMock() на свой объект I18n, потому что я не хочу, чтобы он используйте реальный объект в тесте ChatApp.

Так следующие основные инструкции на сайте шутки, я создал издевается папку и создал макет файл i18n, который создает макет из исходного объекта, а затем переопределяет метод т и добавляет метод, чтобы позволить мне для установки строки возврата для 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 я требую Ложная в перед каждым, например, так:

'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 в пределах test, тогда я получаю правильный издеваемый объект, также запускается __setReturnString (как если бы я console.log в этом сообщении я вижу журнал).

Однако, если я console.log объекта i18n в действительном компоненте React, тогда он получает макет Jest, но он не получает мой Jest mock, поэтому метод t - это пустой метод, который ничего не делает, что означает, что тест не удался.

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

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

ответ

1

Jest делает автоматическая насмешка. Просто i18n = require('../support/i18n') должно быть достаточно. Вот почему вам обычно приходится звонить jest.dontMock.

Вы можете найти более подробную информацию здесь: https://facebook.github.io/jest/docs/automatic-mocking.html

+0

Привет, Спасибо за ввод. Тем не менее, я не хочу, чтобы Jest предоставлял автоматический макет, поскольку функции автоматического макета Jest ничего не возвращают. Который сделал бы мой тест неудачным, поскольку он ожидает, что строка будет переведена и возвращена. Руководство, издеваясь над документами jest, должно быть тем, что мне нужно, поскольку я хочу, чтобы Mocked-версия моего объекта возвращала именно то, что я ему рассказываю. – TheStoneFox

+0

Как насчет того, чтобы попытаться придерживаться автоматического издевательств и настроить макет в тесте? Что-то вроде 'var i18n = require ('i18n'); i18n.t.mockReturnValue ('My return string') – kraf

+2

Привет, я пробовал требовать вещь и высмеивать значение, но в реальной реализации (внутри ChatApp), когда t называется, он все равно возвращается неопределенным, поэтому макет не является за работой. Объект i18n в тесте издевается правильно, но это не объект i18n, используемый в коде ChatApp. – TheStoneFox

5

Я имел проблемы с получением __mocks__ папку работает, как хорошо. Способ, которым я обходился, заключается в использовании метода jest.setMock();.

В вашем случае, вы бы jest.setMock('../../../scripts/i18n/', require('../__mocks__/i18n');

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

Это должно заставлять ваш модуль и все модули, которые вам требуются (включая React), использовать ваш ручной модуль i18n.

0

Что mattykuzyk упоминает в his answer не работает вообще для меня :(

Однако то, что я узнал, как представляется, проблема для меня была установка шутя: Я использовал 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` 
 
))

Хотя я не проверял, добавив __setReturnString должно быть достаточно просто, для меня это было достаточно, чтобы на самом деле вернуть мой перевод ключ. Надеюсь это поможет!