簡體   English   中英

如何模擬React Component的功能並安裝該組件?

[英]How to mock a function of React Component and mount the component?

我有一個使用fetch API獲取帖子的react組件。 現在,在進行“開玩笑的測試”時,我想模擬訪存API方法以從文件返回json數據。 通過查找類計數,安裝要測試的組件以計算帖子數。 下面是代碼。

測試文件代碼

    import React from 'react';
    import { mount } from 'enzyme';
    import dummyjson from '../dummydata.json';
    import DemoApp from '../index';

    describe('xxxx test component', () => {
  it('first test', async () => {
    global.fetch = jest.fn(() => Promise.resolve(dummyjson));
    const wrapper = shallow(<DemoApp />, { disableLifecycleMethods: true });
    expect(wrapper.state('isLoaded')).toBe(false);
    await wrapper.instance().loadPosts();
    expect(wrapper.state('isLoaded')).toBe(true);
  });
    });

反應組件代碼

        import React from 'react';
    /* eslint class-methods-use-this: ['error', { 'exceptMethods': ['fetch'] }] */

    export default class DemoApp extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          error: null,
          isLoaded: false,
          items: [],
        };
      }

   componentDidMount() {
    this.loadPosts().then(
      (result) => {
        this.setState({
          isLoaded: true,
          items: result,
        });
      },
      (error) => {
        this.setState({
          isLoaded: true,
          error,
        });
      },
    );
  }

  loadPosts() {
    return fetch('https://jsonplaceholder.typicode.com/posts')
      .then(res => res.json()).then(result => result)
      .catch(error => error);
  }

      render() {
        const { error, isLoaded, items } = this.state;
        if (error) {
          return <div>Error: {error.message}</div>;
        } else if (!isLoaded) {
          return <div>Loading...</div>;
        }
        return (
          <div>
            {items.map(item => <div className="somecssclass"> {item.title} {item.title}</div>)}
          </div>
        );
      }
    }

下面是dummydata json

    [
    {
      "userId": 1,
      "id": 1,
      "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
      "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
    },
    {
      "userId": 1,
      "id": 2,
      "title": "qui est esse",
      "body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
    }
]

即使我在react組件類文件中為fetch方法提供了以下異常,但我仍在錯誤/警告下出現錯誤。 / * eslint class-methods-use-this:['error',{'exceptMethods':['fetch']}] * /

在此處輸入圖片說明

我們如何解決此警告/錯誤?

非常感謝您的幫助。 謝謝。

有比賽條件。 loadPosts是異步的,而測試是同步的,並且沒有承諾鏈等待fetch承諾鏈完成。

控制流程和測試方法存在問題。 loadPosts需要返回一個promise,因此可以將其鏈接起來:

  loadPosts() {
    return fetch('https://jsonplaceholder.typicode.com/posts')...;
  }

進行單元測試的一種正確方法是在一個測試中測試loadPosts並直接loadPosts進行測試:

  it('...', async () => {
    global.fetch = jest.fn(() => Promise.resolve(dummyjson));
    const wrapper = shallow(<DemoApp />, { disableLifecycleMethods: true });
    expect(wrapper.state('isLoaded').toBe(false);
    await wrapper.instance().loadPosts();
    expect(wrapper.state('isLoaded').toBe(true);
  });

在另一個測試中,可以對loadPosts進行存根/ loadPosts並斷言在componentDidMount調用了它。

還要注意, global.fetch =會一勞永逸地替換它。 最好使用jest.stub

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM