异步 componentDidMount 时使用 React 的 Jest 和 Enzyme 进行测试
Posted
技术标签:
【中文标题】异步 componentDidMount 时使用 React 的 Jest 和 Enzyme 进行测试【英文标题】:Testing with React's Jest and Enzyme when async componentDidMount 【发布时间】:2018-08-31 09:03:29 【问题描述】: 反应:16.3.0-alpha.1 开玩笑:“22.3.0” 酶:3.3.0 打字稿:2.7.1代码:
class Foo extends React.PureComponent<undefined,undefined>
bar:number;
async componentDidMount()
this.bar = 0;
let echarts = await import('echarts'); // async import
this.bar = 100;
测试:
describe('...', () =>
test('...', async () =>
const wrapper = shallow(<Foo/>);
const instance = await wrapper.instance();
expect(instance.bar).toBe(100);
);
);
错误:
Expected value to be:
100
Received:
0
【问题讨论】:
【参考方案1】:解决方案:
1:使用 async/await 语法。
2:使用挂载(不浅)。
3:等待异步组件生命周期。
例如:
test(' ',async () =>
const wrapper = mount(
<Foo />
);
await wrapper.instance().componentDidMount();
)
【讨论】:
这不是您在上面发布的问题中要检查的内容。我的回答是您问题的正确解决方案。 这会导致方法运行两次。 @VivekN 有正确的解决方案。这将运行“componentDidMount”两次。安装后的任何等待都可能“解决”问题,但我认为这不是正确的解决方案。【参考方案2】:这样的东西应该适合你:-
describe('...', () =>
test('...', async () =>
const wrapper = await mount(<Foo/>);
expect(wrapper.instance().bar).toBe(100);
);
);
【讨论】:
这对我来说是最好的解决方案,特别是因为我不想浅装 确实;如果组件的didMount
中有setState
,则需要在expect
之前添加wrapper.update();
。【参考方案3】:
试试这个:
it('should do something', async function()
const wrapper = shallow(<Foo />);
await wrapper.instance().componentDidMount();
app.update();
expect(wrapper.instance().bar).toBe(100);
);
【讨论】:
在通过谷歌查看这个问题并尝试通过 mount 的酶实现异步 componentDidMount 之后。而且“挂载”方式不适合反应原生项目 - 我有很多错误。这个方法帮助了我。而且你不需要安装jsdom和使用mount。 “react”:“16.4.1”,“react-native”:“0.56.0”,“酶”:“^3.4.4”,“jest”:“23.5.0” 这里有什么应用? @Pavan 我认为wrapper.update()
是有意的。 --ref
顺便说一句,await
不会在那里做任何事情,除非你的 componentDidMount()
返回一个承诺【参考方案4】:
这里提供的解决方案都没有解决我的所有问题。最后我找到了https://medium.com/@lucksp_22012/jest-enzyme-react-testing-with-async-componentdidmount-7c4c99e77d2d,它解决了我的问题。
总结
function flushPromises()
return new Promise(resolve => setImmediate(resolve));
it('should do someting', async () =>
const wrapper = await mount(<Foo/>);
await flushPromises();
expect(wrapper.instance().bar).toBe(100);
);
【讨论】:
【参考方案5】:您的测试还需要实现异步、等待。 例如:
it('should do something', async function()
const wrapper = shallow(<Foo />);
const result = await wrapper.instance();
expect(result.bar).toBe(100);
);
【讨论】:
已编辑,执行实例时是否尝试过await?,await基本上是在promise上运行 如果你能分享你的完整测试 我不认为.instance()
会返回一个承诺,所以我认为await
在那里没有做任何事情。 TypeError: wrapper.instance(...).then is not a function
以上是关于异步 componentDidMount 时使用 React 的 Jest 和 Enzyme 进行测试的主要内容,如果未能解决你的问题,请参考以下文章
为啥在 componentDidMount 中取消异步/ajax 请求
ReactJs:如何在渲染之前等待 componentDidMount() 完成?