如何模拟React组件的功能并安装该组件?

时间:2018-10-07 17:56:07

标签: javascript reactjs jestjs

我有一个使用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']}] * /

enter image description here

我们如何解决此警告/错误?

我们非常感谢您的帮助。 谢谢。

1 个答案:

答案 0 :(得分:0)

存在比赛条件。 <h2>Search/Filter Dropdown</h2> <p>Click on the button to open the dropdown menu, and use the input field to search for a specific dropdown link.</p> <div class="dropdown"> <button onclick="myFunction()" class="dropbtn">Dropdown</button> <div id="myDropdown" class="dropdown-content"> <input type="text" placeholder="Search.." id="myInput" onkeyup="filterFunction()"> <a href="#about"><i class="flag a"></i><span>About</span></a> <a href="#base"><i class="flag b"></i><span>Base</span></a> <a href="#blog"><i class="flag b"></i><span>Blog</span></a> <a href="#contact"><i class="flag c"></i><span>Contact</span></a> <a href="#custom"><i class="flag c"></i><span>Custom</span></a> <a href="#support"><i class="flag s"></i><span>Support</span></a> <a href="#tools"><i class="flag t"></i><span>Tools</span></a> </div> </div>是异步的,而测试是同步的,并且没有保证链等待const LoadableComponent = Loadable({ loader: () => import('components/Shared/Logo/Logo'), loading: () => <div>loading</div>, // pass component, not jsx }); 保证链完成。

控制流程和测试方法存在问题。 loadPosts需要返回承诺,因此可以将其链接起来:

fetch

单元测试的一种正确方法是在一项测试中测试loadPosts并直接对其进行测试:

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

在另一个测试中,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会一劳永逸地替换它。最好使用componentDidMount模拟它。