我有一个非常简单的React mixin,它使用jQuery来触发事件
MyMixin = {
trackStructEvent: function () {
args = Array.prototype.slice.call(arguments);
$('body').trigger('myEvent', args);
}
module.exports = MyMixin
使用browserify将其导入主站点,作为一组新组件的一部分。由于拥有这些组件的主站点将始终包含jQuery,我不希望jQuery与browserify一起使用,因为它将被复制。
这在行为方面不是问题 - 但是当运行jest以使用此mixin对组件进行单元测试时会引发问题。
ReferenceError: $ is not defined
我知道我可以通过浏览器包含jQuery来解决这个问题,但是这会将2个副本加载到我的网站中。
有没有什么方法可以告诉我的反应组件jQuery已经存在于窗口而不用担心呢?
答案 0 :(得分:7)
我有类似的问题,但我认为到目前为止我已经解决了你的问题。 您需要在您的react文件中使用require来定义$
下的jQueryjest.dontMock('jquery')
然后你需要告诉jest不要模拟jquery
{{1}}
然后你的jest单元测试应该通过(假设他们没有验证jQuery正在做的事情 - 这是我的测试正在落空的地方)。
你还需要告诉browserify jQuery是外部的,然后结果将是你已经定义了所有对$的引用,jquery库被加载用于测试但是不包含在你的browserify包中。 (使用browserify-shim)
答案 1 :(得分:2)
我要做的是:
if (process.env.NODE_ENV === 'test') window.$ = require('jquery');
我希望这有助于某人!
更新:
我在所有使用jQuery的React文件中开始import $ from 'jquery'
。这消除了对窗口的依赖。$是我期望的jQuery类型(我遇到了其他库弄乱窗口的问题。$。起初,我担心到处导入jQuery,因为我担心这会增加我的捆绑大小。但捆绑的工作方式,所有这些导入将指向单身,所以捆绑大小不会增加。
答案 2 :(得分:2)
就我而言,我对测试组件中的jQuery功能不感兴趣。另外,我没有在我的包中包含jQuery,因为它被使用并包含在我的应用程序所在的网站上。例如,我做了以下事情:
// SubmitRender.js
// ...import statements...
var SubmitRender = React.createClass({
componentWillMount: function () {
$('form').on('submit', (e)=>{
this.handleSubmit(e);
});
},
// ...more code...
});
export default SubmitRender;
// SubmitRender.spec.js
// ...import statements...
describe('SubmitRender', () => {
beforeAll(() => {
// mocking jQuery $()
global.window.$ = jest.fn(() => {return {on: jest.fn()}});
});
it('renders without error', () => {
expect( () => render(<SubmitRender />) ).not.toThrow();
});
});
我知道如果不调用$
函数,我的组件将无法挂载。所以我只是在jest.fn
中使用beforeAll()
模拟该功能。现在,我也知道我的实际组件中的jQuery函数是链接的。所以我知道我还需要考虑jQuery&#39; .on()
,所以我确保返回一个带有on
函数的对象。没有进一步的链接,所以我可以停下来。
如果我有一组更复杂的链式函数,我可以这样做:
beforeAll(() => {
// mocking jQuery $()
var fakeQuery = jest.fn(() => {
return {
on: fakeQuery,
off: fakeQuery,
click: fakeQuery
}
})
global.window.$ = fakeQuery;
});