使用 Jest 模拟 React 组件的依赖
Mock a dependency of a React component using Jest
我有一个 React 组件 (CreateForm)。 React 组件依赖于一个模块(Store)。 CreateForm 有一个取消按钮。单击取消按钮时,应调用 Store 模块的 handleCancel 函数。
我用 Jest 写了一个测试失败:
test.only('should handle cancel button click', () => {
jest.mock('../../src/store');
const store = require('../../src/store');
const wrapper = shallow(<CreateForm />);
const cancelButton = wrapper.find('button').at(1);
cancelButton.simulate('click');
expect(store.default.handleCancel).toBeCalled();
});
测试失败。模拟函数没有被调用,测试失败。反应组件没有得到这个版本的模拟吗?如果是这样,我该如何解决测试?谢谢
我的 CreateForm 组件如下所示:
import Store from './store';
render() {
return (
<Panel>
<FormControls />
<button onClick={Store.create}>Create</button>
<button onClick={Store.handleCancel}>Cancel</button>
</Panel>
);
}
第二个适合我的即兴测试如下所示。
test.only('should handle cancel button click', () => {
const store = require('../../src/store').default;
const cancel = store.handleCancel;
store.handleCancel = jest.fn();
const wrapper = shallow(<CreateForm />);
const cancelButton = wrapper.find('button').at(1);
cancelButton.simulate('click');
expect(store.handleCancel).toBeCalled();
store.handleCancel = cancel;
});
以上测试有效。我正在手动模拟该功能,进行测试并在测试后将功能恢复到原来的状态。有没有更好的方法或 Jest 方法来编写上述测试?谢谢
你忘了告诉 jest 如何模拟商店模块,在你的情况下它只是 undefined
。
const store = require('../../src/store');
jest.mock('../../src/store', () =>({
handleCancel: jest.fn()
}));
test.only('should handle cancel button click', () => {
const wrapper = shallow(<CreateForm />);
const cancelButton = wrapper.find('button').at(1);
cancelButton.simulate('click');
expect(store.default.handleCancel).toBeCalled();//I'm not sure about the default here
});
使用此解决方案,您可以告诉 jest 使用具有 handleCancel
函数的对象来模拟商店,这是一个 jest 间谍。然后你可以在这个间谍上测试它是否被调用。
这就是我使用 Jest 监视导入函数的方法。
导入您正在测试的文件中导入的所有内容。
在 beforeEach
中模拟它,如果你需要 return 值或其他任何东西,你可以使用更复杂的模拟。
在 afterEach
中调用 jest.clearAllMocks()
将所有功能重置为正常,以阻止任何模拟落入其他测试。
把它们放在一起看起来像这样。
import shallow from 'enzyme'
import * as Store from './Store' // This should be the actual path from the test file to the import
describe('mocking', () => {
beforeEach(() => {
jest.spyOn(Store, 'handleCancel')
jest.spyOn(Store, 'create')
})
afterEach(() => {
jest.clearAllMocks();
})
test.only('should handle cancel button click', () => {
const wrapper = shallow(<CreateForm />);
const cancelButton = wrapper.find('button').at(1);
cancelButton.simulate('click');
expect(Store.handleCancel).toBeCalled();
})
})
此外,如果您需要模拟默认导入,您可以这样做。 jest.spyOn(Store, 'default')
我有一个 React 组件 (CreateForm)。 React 组件依赖于一个模块(Store)。 CreateForm 有一个取消按钮。单击取消按钮时,应调用 Store 模块的 handleCancel 函数。
我用 Jest 写了一个测试失败:
test.only('should handle cancel button click', () => {
jest.mock('../../src/store');
const store = require('../../src/store');
const wrapper = shallow(<CreateForm />);
const cancelButton = wrapper.find('button').at(1);
cancelButton.simulate('click');
expect(store.default.handleCancel).toBeCalled();
});
测试失败。模拟函数没有被调用,测试失败。反应组件没有得到这个版本的模拟吗?如果是这样,我该如何解决测试?谢谢
我的 CreateForm 组件如下所示:
import Store from './store';
render() {
return (
<Panel>
<FormControls />
<button onClick={Store.create}>Create</button>
<button onClick={Store.handleCancel}>Cancel</button>
</Panel>
);
}
第二个适合我的即兴测试如下所示。
test.only('should handle cancel button click', () => {
const store = require('../../src/store').default;
const cancel = store.handleCancel;
store.handleCancel = jest.fn();
const wrapper = shallow(<CreateForm />);
const cancelButton = wrapper.find('button').at(1);
cancelButton.simulate('click');
expect(store.handleCancel).toBeCalled();
store.handleCancel = cancel;
});
以上测试有效。我正在手动模拟该功能,进行测试并在测试后将功能恢复到原来的状态。有没有更好的方法或 Jest 方法来编写上述测试?谢谢
你忘了告诉 jest 如何模拟商店模块,在你的情况下它只是 undefined
。
const store = require('../../src/store');
jest.mock('../../src/store', () =>({
handleCancel: jest.fn()
}));
test.only('should handle cancel button click', () => {
const wrapper = shallow(<CreateForm />);
const cancelButton = wrapper.find('button').at(1);
cancelButton.simulate('click');
expect(store.default.handleCancel).toBeCalled();//I'm not sure about the default here
});
使用此解决方案,您可以告诉 jest 使用具有 handleCancel
函数的对象来模拟商店,这是一个 jest 间谍。然后你可以在这个间谍上测试它是否被调用。
这就是我使用 Jest 监视导入函数的方法。
导入您正在测试的文件中导入的所有内容。
在 beforeEach
中模拟它,如果你需要 return 值或其他任何东西,你可以使用更复杂的模拟。
在 afterEach
中调用 jest.clearAllMocks()
将所有功能重置为正常,以阻止任何模拟落入其他测试。
把它们放在一起看起来像这样。
import shallow from 'enzyme'
import * as Store from './Store' // This should be the actual path from the test file to the import
describe('mocking', () => {
beforeEach(() => {
jest.spyOn(Store, 'handleCancel')
jest.spyOn(Store, 'create')
})
afterEach(() => {
jest.clearAllMocks();
})
test.only('should handle cancel button click', () => {
const wrapper = shallow(<CreateForm />);
const cancelButton = wrapper.find('button').at(1);
cancelButton.simulate('click');
expect(Store.handleCancel).toBeCalled();
})
})
此外,如果您需要模拟默认导入,您可以这样做。 jest.spyOn(Store, 'default')