使用玩笑来获取测试

时间:2018-12-15 00:19:22

标签: javascript reactjs jestjs

我已经实现了以下获取和测试用例,但这给了我错误(我在单元测试中很差)。

Main.js

import React, { Component } from 'react';

class Main extends Component {
    constructor(props) {
        super(props);

        this.state = { 
            testData: [],
        }
    }

    componentDidMount() {
        fetch(`http://testurl.com/testData`)
        .then(response => response.json())
        .then(result => this.setState({ testData: result }));
    }

    render() {
        const {testData} = this.state;

        return ( 
            <div className="main"> 
                { testData.data && 
                    <section>
                        <CustomComponent movies={ testData.data } />
                    </section> 
                }
            </div>
        );
    }
}

export default Main;

Main.test.js

import React from 'react';
import ReactDOM from 'react-dom';
import { mount, shallow } from 'enzyme';
import { fetchMock } from 'fetch-mock';
import Main from "../src/Main";
import testData from './_mockData_/testData'

it('should render without crashing', () => {
    const div = document.createElement('div');
    ReactDOM.render(<Main />, div);
    ReactDOM.unmountComponentAtNode(div);
  });

describe('should renders Main correctly', () => {
    fetch('http://testurl.com/testData').then(res => {
        expect(res.data).toEqual(testData)
  })
});

即使我尝试使用http://www.wheresrhys.co.uk/fetch-mock/,也没有任何效果。

describe('should renders Main correctly', () => {
    fetchMock.get('http://testurl.com/testData').then(res => {
        expect(res.data).toEqual(testData)
  })
});

总是出现以下错误。

  

参考错误:提取未定义

任何帮助将不胜感激。

已编辑:

根据评论,我按如下方式编辑了代码,但没有运气。

import testData from './_mockData_/testData'

describe('Main', () => {
    it('renders without crashing', () => {
        const tree = shallow(<Main />);
        expect(tree).toMatchSnapshot();
      });

      beforeEach(() => {
        fetch.resetMocks()
      })

      it('calls API and returns data to me', () => {
        fetch.mockResponseOnce(JSON.stringify({ someData: testData }))

        //assert on the response
        fetch(`http://testurl.com/testData`).then(res => {
          expect(res.data).toEqual(testData)
        })

        //assert on the times called and arguments given to fetch
        expect(fetch.mock.calls.length).toEqual(1)
        expect(fetch.mock.calls[0][0]).toEqual('http://testurl.com/testData')
      })
});

出现以下错误:

  

TypeError:无法读取未定义的属性'then'

1 个答案:

答案 0 :(得分:0)

这是仅使用enzyme v3和jestjs的解决方案,仅此而已。

main.tsx

import React, { Component } from 'react';
import { CustomComponent } from './CustomComponent';
import fetch from 'node-fetch';

interface IMainState {
  testData: {
    data: any[];
  };
}

class Main extends Component<any, IMainState> {
  constructor(props) {
    super(props);

    this.state = {
      testData: {
        data: []
      }
    };
  }

  public componentDidMount() {
    fetch(`http://testurl.com/testData`)
      .then(response => response.json())
      .then(result => this.setState({ testData: result }));
  }

  public render() {
    const { testData } = this.state;

    return (
      <div className="main">
        {testData.data && (
          <section>
            <CustomComponent movies={testData.data} />
          </section>
        )}
      </div>
    );
  }
}

export default Main;

单元测试:

main.spec.tsx

import React from 'react';
import { shallow } from 'enzyme';
import Main from './main';
import fetch from 'node-fetch';

const { Response } = jest.requireActual('node-fetch');

jest.mock('node-fetch');

describe('Main', () => {
  it('t1', done => {
    (fetch as jest.MockedFunction<typeof fetch>).mockResolvedValueOnce(
      new Response(
        JSON.stringify({
          data: ['data1', 'data2']
        })
      )
    );
    const wrapper = shallow(<Main></Main>);
    expect(fetch).toBeCalledWith(`http://testurl.com/testData`);
    expect(wrapper).toMatchSnapshot();
    setImmediate(() => {
      expect(wrapper.state()).toEqual({
        testData: {
          data: ['data1', 'data2']
        }
      });
      expect(wrapper).toMatchSnapshot();
      done();
    });
  });
});

具有覆盖范围的单元测试结果:

 PASS  src/stackoverflow/53788454/main.spec.tsx (5.517s)
  Main
    ✓ t1 (28ms)

 › 1 snapshot written.
---------------------|----------|----------|----------|----------|-------------------|
File                 |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
---------------------|----------|----------|----------|----------|-------------------|
All files            |    95.83 |      100 |     87.5 |    95.24 |                   |
 CustomComponent.tsx |    85.71 |      100 |       50 |    83.33 |                 9 |
 main.tsx            |      100 |      100 |      100 |      100 |                   |
---------------------|----------|----------|----------|----------|-------------------|
Snapshot Summary
 › 1 snapshot written from 1 test suite.

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   1 written, 1 passed, 2 total
Time:        6.515s

组件快照:

// Jest Snapshot v1

exports[`Main t1 1`] = `
<div
  className="main"
>
  <section>
    <CustomComponent
      movies={Array []}
    />
  </section>
</div>
`;

exports[`Main t1 2`] = `
<div
  className="main"
>
  <section>
    <CustomComponent
      movies={
        Array [
          "data1",
          "data2",
        ]
      }
    />
  </section>
</div>
`;

以下是完整的演示:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/53788454

关于如何手动模拟node-fetch,请看一下https://jestjs.io/docs/en/bypassing-module-mocks