samedi 14 février 2015

How do you manually mock one of your own files in Jest?

I'm trying to mock an object (which I created) in Jest so I can provide default behaviour within the react component (so the real implementation isn't used)


This is my react component ChatApp (it's very straight forward)



'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;


So I have a custom I18n dependency that does translations (I18n is something I've written that is a wrapper for node-polyglot).


So I want to do a basic test to see if the H1 has the correct word in it, but I don't want to set jest.dontMock() on my I18n object, because I don't want it to use the real object in the ChatApp test.


So following the basic instructions on the jest website, I created a mocks folder and created a mock file for i18n, which generates a mock from the original object and then overrides the t method and adds a method to allow me to set the return string for t.


This is the mock object



'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;


Now in my ChatApp test I require the mock in a before each, like so:



'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');
});
});


If i console.log the i18n object within the test then I get the correct mocked object, the __setReturnString also gets triggered (as if I console.log in that message I see the log).


However, if I console.log the i18n object within the actual React component then it gets a Jest mock but it doesn't get my Jest mock, so the t method is an empty method that doesn't do anything, meaning the test fails.


Any ideas what I'm doing wrong?


Thanks a lot


Aucun commentaire:

Enregistrer un commentaire