代码之家  ›  专栏  ›  技术社区  ›  Learner

使用fetch检查组件是否在不设置酶状态的情况下呈现

  •  0
  • Learner  · 技术社区  · 5 年前

    我正在尝试运行一个基本的应用程序,我正在调用一个正在节点层运行的api。我在react应用程序的package.json中使用代理,这就是为什么我使用相对url调用fetch。

    节点在端口4000中运行,react在3000中运行。

    因此,当我在成功后调用api时,我会将加载状态更改为false,最初当api调用请求发生时,加载程序将出现,因为加载在成功后datacomponent将出现。

    基本上,在响应将initital loading设置为false以加载datacomponent之后,initital loading将为false

    在这里我无法看到datacomponent,我如何检查datacomponent的呈现。

    // app.js
    
    class App extends Component {
      state = {
        loading: true,
        data: null
      }
    
      componentDidMount() {
        this.fetchData();
      }
    
      fetchData = async() => {
        const jsonRes = await fetch("/api/user");
        const data = await jsonRes.json();
        this.setState({
          loading: false,
          data
        })
      }
    
      render() {
        if (this.state.loading) {
          return ( <
            div className = "laoder-container" > < Loader / > < /div>
          )
        } else {
          return ( <
            DataComponent data = {
              this.state.data
            }
            />
          )
        }
      }
    }
    
    
    //app.test.js
    import React from 'react'
    import App from './App';
    import {
      mount
    } from 'enzyme'
    
    describe('app.js', () => {
      it('should render the app component once data is there', () => {
        global.fetch = jest.fn().mockImplementation(() => {
          var p = new Promise((resolve, reject) => {
            resolve({
              ok: true,
              json: function() {
                return {
                  userName: 'John',
                  surName: 'Doe'
                }
              }
            });
          });
    
          return p;
        });
      })
    
      const wrapper = mount( < App / > )
      expect(fetch).toBeCalled();
      wrapper.update();
      console.log(wrapper.debug()) // not showing the Data component
    
    })
    0 回复  |  直到 5 年前
        1
  •  0
  •   Matty J    5 年前

    问题是提取是异步进行的。你打电话的时候 wrapper.debug() 状态无法更新,因为 fetch 已将响应放入事件堆栈。所以 取来 已被呼叫 ,但它没有返回任何响应。

    您可以通过将测试更新为以下内容来看到这一点:

    // mock out fetch...
    const wrapper = mount(<App />);
    expect(fetch).toBeCalled();
    setTimeout(() => {
      wrapper.update();
      console.log(wrapper.debug()); // should be showing the Data component now
    }, 0);
    

    这样就可以调用承诺回调 之前 尝试通过将更新/调试代码放在事件堆栈的末尾来查看呈现的标记。

    你可以把它包起来 setTimeout 在一个承诺中 it 回调函数,并放置 expects 在你面前 resolve (否则它可能永远不会运行 expect 测试结束前的功能)。

    // mock out fetch...
    const wrapper = mount(<App />);
    expect(fetch).toBeCalled();
    return new Promise((resolve) => {
      setTimeout(() => {
        wrapper.update();
        console.log(wrapper.debug()); // should be showing the Data component now
        expect(...)
        resolve();
      }, 0);
    });
    

    另一种方法是测试当状态具有特定数据时,数据的结果是否呈现您所期望的结果:

    it("should render the app component once data is there", () => {
      const wrapper = shallow(<App />);
      wrapper.setState({
        loading: false,
        data: {
          userName: "John",
          surName: "Doe"
        }
      });
      console.log(wrapper.debug()); // You'll see the DataComponent
    });