我有以下智能组件,它使用componentWillMount生命周期方法进行异步调用以获取数据。我正在为它编写测试但我无法测试函数是否被调用,如果是,它在组件被挂载之前被调用。它们是重要的案例。
智能组件的代码如下:
const mapStateToProps = (state) => { const context = state.context; return {
isError: context.error, }; };
const options = { componentWillMount: (props) => {
const { dispatch } = props;
dispatch(fetchContextUser()); }, };
export function App(props) { return (
<div className="app">
{ props.isError ? (<ContextError />) : (<Main />) }
{ props.children }
</div> ); }
App.propTypes = { children: PropTypes.object, // eslint-disable-line react/forbid-prop-types isError: PropTypes.bool.isRequired, // eslint-disable-line react/forbid-prop-types };
export default connect(mapStateToProps, null)(functional(App, options));
我正在使用Enzyme,Chai和其他模拟适配器来测试这个组件。测试块如下:
describe.only('Render Connected Component', () => { let store; beforeEach(() => {
store = mockStore({
context: {
error: false,
},
}); }); it('Should render connected components', () => {
const connectedWrapper = mount(
<Provider store={store}>
<ConnectedApp />
</Provider>
);
expect(connectedWrapper).to.be.present(); }); });
我只想测试两件事:
1。)调用fetchContextUser 2.)在组件挂载之前调用fetchContextUser
答案 0 :(得分:0)
我认为您只需测试componentWillMount
方法调用fetchContextUser
操作,因为您必须相信 ReactJS 会调用componentWillMount
在安装之前的方法,所以,这个前提测试你的第二个案例。
所以,为了测试第一个案例,我认为你可以这样做:
import sinon from 'sinon';
...
it('It calls fetchContextUser when calls componentWillMount', () => {
const fetchContextUserSpy = sinon.spy();
const wrapper = shallow(<App fetchContextUser={fetchContextUserSpy} />);
fetchContextUserSpy.reset(); //reset the spy to avoid unwanted calls
wrapper.instance().componentWillMount(); // Call componentWillMount directly
expect(fetchContextUserSpy.calledOnce).to.be.true; // Expect that after call componentWillMount() the fetchContextUserSpy was called once
在此测试中,您只需直接调用componentWillMount()函数并期望调用fetchContextUserSpy,以便测试 case 1 。 我正在使用 sinon.js 来测试函数的调用时间。
再次案例2 不需要进行测试,因为 ReactJS 保证在安装组件之前调用componentWillMount方法。
=============================================== ==========================
尝试使用功能组件
it('It calls fetchContextUser when mounted', () => {
const fetchContextUserSpy = sinon.spy();
const wrapper = shallow(<App fetchContextUser={fetchContextUserSpy} />);
expect(fetchContextUserSpy.calledOnce).to.be.true; // Expect that the component calls the fetchContextUserSpy
});
答案 1 :(得分:0)
我认为@ pedro-jiminez很接近,但在这里缺少两个元素:
componentWillMount
,您需要使用mount
,而不是shallow
fetchContextUser
是道具,可以用间谍代替。在这种情况下,您可能希望在测试中存根store.dispatch
并断言它是使用fetchContextUser
调用的,假设它只是一个纯函数。所以测试看起来像:
describe.only('Render Connected Component', () => {
let store;
beforeEach(() => {
store = mockStore({
context: {
error: false,
},
});
// stub dispatch
sinon.stub(store.dispatch);
});
it('Should render connected components', () => {
const connectedWrapper = mount(
<Provider store={store}>
<ConnectedApp />
</Provider>
);
expect(connectedWrapper).to.be.present();
// Now test dispatch called
expect(store.dispatch.calledOnce).to.be.true;
expect(store.dispatch.args[0][0]).to.deepEqual(fetchContextUser());
});
});