reactjs - Jest - 如何测试 react 方法的输出是否正确?

标签 reactjs jestjs babel-jest

我在尝试了解如何使用 Jest 测试 react 文件中方法的输出时遇到问题。我对这种 Web 开发风格完全陌生,因此非常感谢您的帮助。

我有一个这样的 js 文件:

import * as React from 'react';
import 'es6-promise';
import 'isomorphic-fetch';

export default class FetchData extends React.Component {
    constructor() {
        super();
        this.state = { documents: [], loading: true };
        fetch('api/SampleData/GetDocuments')
            .then(response => response.json())
            .then(data => {
                this.setState({ documents: data, loading: false });
            });
    }

    render() {
        let contents = this.state.loading ? <p><em>Loading...</em></p>
            : FetchData.renderdocumentsTable(this.state.documents);

        return <div>
            <button onClick={() => { this.refreshData() }}>Refresh</button>
            <p>This component demonstrates bad document data from the server.</p>
            {contents}
        </div>;
    }

    refreshData() {
        fetch('api/SampleData/GetDocuments')
            .then(response => response.json())
            .then(data => {
                this.setState({ documents: data, loading: false });
            });
    }

    static renderdocumentsTable(documents) {
        return <table className='table'>
            <thead>
                <tr>
                    <th>Filename</th>
                    <th>CurrentSite</th>
                    <th>CorrectSite</th>
                </tr>
            </thead>
            <tbody>
                {documents.map(document =>
                    <tr className="document-row" key={document.documentId}>
                        <td>{document.filename}</td>
                        <td>{document.currentSite}</td>
                        <td>{document.correctSite}</td>
                    </tr>
                )}
            </tbody>
        </table>;
    }
}

我基本上希望能够测试返回的表中的列数是否正确,但是我不知道如何使用 Jest 执行此操作。

谢谢, 亚历克斯

最佳答案

我遵循下一个方法:

  1. Mocking dependencies由被测组件显式调用。
  2. 使用 shallow() 初始化组件
  3. 尝试不同的修改
  4. 使用 .toMatchSnapshot() 检查组件

在“尝试不同的修改”下,我的意思是要么创建具有不同初始 props 的组件,要么与组件的内部元素的 props 进行交互。

test('closes list on button clicked', () => {
    let wrapper = shallow(<MyComponent prop1={'a'} prop2={'b'} />);
    wrapper.find('button').at(0).simulate('click');
    expect(wrapper).toMatchSnapshot();
});

这样您就无需单独测试方法。为什么我认为这是有道理的?

虽然所有的方法测试都通过了,但我们仍然不能说它是否作为一个整体起作用(假阳性 react )。 此外,如果我们进行任何重构,如重命名方法,我们的 tests-per-method 将失败。与此同时,组件可能仍然可以正常工作,我们花费更多时间来修复测试只是为了让它们通过(假阴性 react )。

从相反的角度关注 render() 结果(这就是 enzyme 适配器在 .toMatchSnapshot() 匹配器的作用下所做的)我们测试我们的元素作为React 项目的一部分。

[UPD] 基于您的代码的示例:

describe("<FetchData />", () => {
  let wrapper;
  global.fetch = jest.fn();

  beforeEach(() => {
    fetch.mockClear();
  });

  function makeFetchReturning(documents) {
    fetch.mockImplementation(() => Promise.resolve({ json: () => documents }));
  }

  function initComponent() {
    // if we run this in beforeEach we would not able to mock different return value for fetch() mock
    wrapper = shallow(<FetchData />); 
  }

  test("calls appropriate API endpoint", () => {
    makeFetchReturning([]);
    initComponent();
    expect(fetch).toHaveBeenCalledWith("api/SampleData/GetDocuments");
  });

  test("displays loading placeholder until data is fetched", () => {
    // promise that is never resolved
    fetch.mockImplementation(() => new Promise(() => {})); 
    initComponent();
    expect(wrapper).toMatchSnapshot();
  });

  test("looks well when empty data returned", () => {
    makeFetchReturning([]);
    initComponent();
    expect(wrapper).toMatchSnapshot();
  });

  test("reloads documents and displays them", () => {
    makeFetchReturning([]);
    initComponent();
    // no matter what values we include in mock but it should be something non-empty
    makeFetchReturning([{fileName: '_', currentSite: '1', correctSite: '2'}]);
    wrapper.find('button').at(0).simulate('click');
    expect(fetch).toHaveBeenCalledTimes(2);
    expect(wrapper).toMatchSnapshot();
  })

});

关于reactjs - Jest - 如何测试 react 方法的输出是否正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53376966/

相关文章:

reactjs - validateDOMNesting 警告 React

javascript - 似乎无法用 Jest 模拟点击事件

reactjs - 如何使用Width HOC模拟Material-UI

css - 在带样式的组件中使图像重叠

javascript - 如何将 Javascript 变量集成到 ReactJS JSX 样式元素中

reactjs - 如何使用 Jest 测试异步存储?

reactjs - 如何测试 Redux Action 创建者

javascript - 需要 Babel "^7.0.0-0",但加载了 "6.26.0"

javascript - 使用最新版本的 d3-path 配置 jest

ruby-on-rails - 使用 Rails + Webpacker + Jest 测试 .js.erb 文件