我有一个有条件的渲染组件(有条件渲染)(如果获取数据则渲染,否则返回null),我想用jest & enzyme
进行测试。我遇到的问题是我想测试该类中的一种方法,但是.instance()
始终返回null,因此不允许我测试该实例。
我的代码看起来像这样
export default class MyComponent extends React.Component<Props, State> {
componentDidMount() {
this.props.fetchData.then(() =>
this.setState({ loaded: true });
);
}
methodThatIWantToTest() {
//do some stuff here
}
render() {
if (this.loaded) {
// render stuff here
} else {
return null;
}
}
}
在测试中我想测试
describe('myComponent', () => {
it('should do some stuff', () => {
const shallowWrapper = shallow(<MyComponent {...props}/>);
const method = shallowWrapper.instance().methodThatIWantToTest();
....such and such
});
});
,但看起来MyComponent
仅返回null,因此shallowWrapper.instance()
也返回null。我尝试了shallowWrapper.update()
和许多其他操作,但似乎根本不想渲染。.如何等待组件更新然后启动expect
语句?
有人遇到过与我类似的问题,并且知道如何解决此问题吗?
答案 0 :(得分:0)
这是一个有效的示例:
myComponent.js
import * as React from 'react';
export default class MyComponent extends React.Component {
constructor(...props) {
super(...props);
this.state = { loaded: false };
}
componentDidMount() {
this.props.fetchData().then(() =>
this.setState({ loaded: true })
);
}
methodThatIWantToTest() {
return 'result';
}
render() {
if (this.state.loaded) {
return <div>loaded</div>;
} else {
return null;
}
}
}
myComponent.test.js
import * as React from 'react';
import { shallow } from 'enzyme';
import MyComponent from './myComponent';
describe('myComponent', () => {
it('should do some stuff', async () => {
const fetchData = jest.fn(() => Promise.resolve());
const props = { fetchData };
const shallowWrapper = shallow(<MyComponent {...props}/>);
expect(shallowWrapper.html()).toBe(null);
expect(shallowWrapper.instance().methodThatIWantToTest()).toBe('result');
// pause the test and let the event loop cycle so the callback
// queued by then() within componentDidMount can run
await Promise.resolve();
expect(shallowWrapper.html()).toBe('<div>loaded</div>');
});
});
答案 1 :(得分:0)
它是render
的结果,而不是null
的实例。 shallowWrapper.instance()
是组件类的实例,对于有状态组件,它不能是null
。正如the reference所述:
返回(反应16.x)
ReactComponent:有状态的React组件实例。
null:如果包装了无状态React组件。
shallowWrapper.html()
最初确实是null
。
原始代码有误,应为this.state.loaded
而不是this.loaded
:
MyComponent extends React.Component {
state = { loaded: false };
componentDidMount() {
this.props.fetchData.then(() => {
this.setState({ loaded: true });
});
}
methodThatIWantToTest() {
//do some stuff here
}
render() {
if (this.state.loaded) {
return <p>hi</p>;
} else {
return null;
}
}
}
componentDidMount
和methodThatIWantToTest
最好被视为不同的单位。它们属于不同的测试。如果在生命周期挂钩中调用methodThatIWantToTest
,则可能在componentDidMount
测试中将其存根:
it('should fetch data', async () => {
const props = { fetchData: Promise.resolve('data') };
const shallowWrapper = shallow(<MyComponent {...props}/>);
expect(shallowWrapper.html()).toBe(null);
await props.fetchData;
expect(shallowWrapper.html()).toBe('<p>hi</p>');
});
然后可以单独测试该方法。可以禁用生命周期挂钩,以减少活动部件的数量:
it('should do some stuff', () => {
const shallowWrapper = shallow(<MyComponent {...props}/>, {disableLifecycleMethods: true});
const result = shallowWrapper.instance().methodThatIWantToTest();
expect(result).toBe(...);
});