【问题标题】:Testing with React's Jest and Enzyme when async componentDidMount异步 componentDidMount 时使用 React 的 Jest 和 Enzyme 进行测试
【发布时间】: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

【问题讨论】:

    标签: reactjs typescript jestjs enzyme


    【解决方案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
      猜你喜欢
      • 2018-12-23
      • 2016-11-13
      • 2019-06-25
      • 2020-01-20
      • 2020-11-25
      • 2020-03-15
      • 1970-01-01
      • 2022-01-18
      • 2017-11-26
      相关资源
      最近更新 更多