javascript 你如何在 Jest 中手动模拟你自己的文件之一?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28514868/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you manually mock one of your own files in Jest?
提问by TheStoneFox
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)
我正在尝试在 Jest 中模拟一个对象(我创建的),以便我可以在 react 组件中提供默认行为(因此不使用真正的实现)
This is my react component ChatApp (it's very straight forward)
这是我的 React 组件 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;
So I have a custom I18n dependency that does translations (I18n is something I've written that is a wrapper for node-polyglot).
所以我有一个自定义的 I18n 依赖项来进行翻译(I18n 是我写的东西,它是 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.
所以我想做一个基本的测试,看看 H1 中是否有正确的单词,但我不想在我的 I18n 对象上设置 jest.dontMock(),因为我不想它使用真实的对象在 ChatApp 测试中。
So following the basic instructions on the jest website, I created a mocksfolder 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.
所以按照jest网站上的基本说明,我创建了一个mocks文件夹并为i18n创建了一个mock文件,它从原始对象生成一个mock然后覆盖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:
现在在我的 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');
});
});
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).
如果我在测试中 console.log i18n 对象然后我得到正确的模拟对象, __setReturnString 也会被触发(就像我在该消息中的 console.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.
但是,如果我 console.log 实际 React 组件中的 i18n 对象,那么它会得到一个 Jest 模拟,但它没有得到我的 Jest 模拟,所以 t 方法是一个不做任何事情的空方法,这意味着测试失败.
Any ideas what I'm doing wrong?
任何想法我做错了什么?
Thanks a lot
非常感谢
回答by MattyKuzyk
I've had trouble getting the __mocks__
folder working as well. The way I got around it is by using the jest.setMock();
method.
我也无法使__mocks__
文件夹正常工作。我绕过它的jest.setMock();
方法是使用方法。
In your case, you would jest.setMock('../../../scripts/i18n/', require('../__mocks__/i18n');
在你的情况下,你会 jest.setMock('../../../scripts/i18n/', require('../__mocks__/i18n');
Obviously, I am not certain of the location of your mock and the location of the real library you're using, but the first parameter should use the path where your real module is stored and the second should use the path where your mock is stored.
显然,我不确定你的模拟的位置和你正在使用的真实库的位置,但第一个参数应该使用你的真实模块的存储路径,第二个应该使用你的模拟存储的路径.
This should force your module and all modules that yours require (including React) to use your manually mocked i18n module.
这应该会强制您的模块和您需要的所有模块(包括 React)使用您手动模拟的 i18n 模块。
回答by kraf
Jest does automatic mocking. Just i18n = require('../support/i18n')
should be enough. That's why you usually have to call jest.dontMock
in the first place.
Jest 会自动模拟。只是i18n = require('../support/i18n')
应该够了。这就是为什么你通常必须首先打电话的原因jest.dontMock
。
You can find more information here: https://facebook.github.io/jest/docs/automatic-mocking.html
您可以在此处找到更多信息:https: //facebook.github.io/jest/docs/automatic-mocking.html
回答by Iris Schaffer
What mattykuzykmentions in his answerdid not work at all for me :(
什么mattykuzyk提到了他的回答并没有在所有的工作对我来说:(
However, what I found out seemed to be the problem for me was the setup of jest: I used moduleNameMapper
in the beginning, and for some reason these are never mocked...
然而,我发现对我来说似乎是问题的设置:我moduleNameMapper
在开始时使用过,出于某种原因,这些从来没有被嘲笑过......
So for me the first step was to instead move my module name mapped folder to the moduleDirectories
to get anything to work.
所以对我来说,第一步是将我的模块名称映射文件夹移动到moduleDirectories
以使其正常工作。
After that, I could simply add a __mocks__
file adjacent to the actual implementation (in my case utils/translation.js
and utils/__mocks__/translation.js
).
As my translations.js
default exports a translation function, I also default exported my mock. The entire __mocks__/translations.js
is super simply and looks like this:
在那之后,我可以简单地增加一个__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`
))
Although I haven't tested it, adding a __setReturnString
should be easy enough, for me it was sufficient to actually return my translation key. Hope this helps!
虽然我还没有测试过,但添加 a__setReturnString
应该很容易,对我来说,实际返回我的翻译密钥就足够了。希望这可以帮助!