在ComponentDidMount()中对Axios请求进行Jest /酶单元测试

时间:2018-10-10 17:03:24

标签: reactjs jestjs enzyme

我正在尝试使用Jest和Enzyme在我现有的react应用程序上执行一些单元测试。我对这些东西完全陌生,准确地说,我不知道该如何处理这样的测试场景。我知道要测试API请求调用,我必须执行一些“模拟”,但是我应该如何为此编写测试?将需要遵循哪些步骤?

以下是我要测试的代码段。

  

Home.js

import React,{Component} from 'react'
import axios from 'axios';
import {Link} from 'react-router-dom';
import FacilityModal from '../Table/FacilityModal';

class Home extends Component {
      state = {
    cities:[],
    name:''
  }

 componentDidMount()   {   axios.get('/cities').then(res => {
       this.setState({cities:res.data})
       console.log("Oza" + JSON.stringify(res))
     });   console.log(this.state.cities)   }

   render(){

let postList = this.state.cities.map(city =>
{
  return(
      <div key = {city.id}>
      <p>
      <Link to = {'/'+city.id}>{city.name}</Link></p>
      </div>
      )
})
return(
    <div className = 'align'>All Facilities (NCAL)

<div className="hr-sect">OR</div>
   <div className = 'Modal'>
            {postList}
        </div>
<FacilityModal cityname = {this.props} />
      </div>
    )
  }

}

2 个答案:

答案 0 :(得分:0)

1)用另一种方法返回API(例如fetchCities())提取API调用,以简化测试。

2)用Jest模拟axios节点模块。请参阅文档:https://jestjs.io/docs/en/mock-functions#mocking-modules

3)使用酶获取对您的组件的引用:https://airbnb.io/enzyme/docs/api/ShallowWrapper/shallow.html

就位后,您可以验证状态是否正确设置。例如:

test('should fetch users', () => {
  const wrapper = shallow(<Home/>);
  const resp = {data: [{cities: ['NY']}]};

  axios.get.mockResolvedValue(resp);

  wrapper.instance().fetchCities().then(resp => {
     expect(wrapper.state('cities')).toEqual(resp.data.cities);
  });

}); 

如何改善此答案?我所期望的不是城市的名字。

axios.js(承诺的单独功能)

'use strict';
module.exports = {
  get: () => {
    return Promise.resolve({
      data: [
        {
          id: 0,
          name: 'Santa Clara'
        },
        {
          id: 1,
          name: 'Fremont'
        }
      ]
    });
  }
};

Home.test.js(实际测试文件)

import React from 'react';
import { shallow,configure } from 'enzyme';
import Home from './Home';
import axios from 'axios';
import Adapter from 'enzyme-adapter-react-16';

configure({adapter:new Adapter()});

jest.mock('axios');


describe('Home component', () => {
  describe('when rendered', () => {
    it('should fetch a list of cities', () => {
      const getSpy = jest.spyOn(axios, 'get');
      const cityInstance = shallow(
        <Home/>
      );
      expect(getSpy).toBeCalled();
    });
  });
});

答案 1 :(得分:0)

import React from 'react';
import axios from 'axios';

export default class ArticleList extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      articles: []
    }
  }

  componentDidMount() {
    return axios.get('GET_ARTICLES_URL').then(response => {
      this.setState({
        articles: response.data
      });
    });
  }

  render() {
    return (
      <ul>
        {this.state.articles.map(a => <li><a href={a.url}>{a.title}</a></li>)}
      </ul>
    )
  }
}

// ---------

import React from 'react';
import { shallow } from 'enzyme';
import App from './App';

jest.mock('axios', () => {
  const exampleArticles = [
    { title: 'test article', url: 'test url' }
  ];
  
  return {
    get: jest.fn(() => Promise.resolve(exampleArticles)),
  };
});

const axios = require('axios');

it('fetch articles on #componentDidMount', () => {
  const app = shallow(<App />);
  app
    .instance()
    .componentDidMount()
    .then(() => {
      expect(axios.get).toHaveBeenCalled();
      expect(axios.get).toHaveBeenCalledWith('articles_url');
      expect(app.state()).toHaveProperty('articles', [
        { title: 'test article', url: 'test url' }
      ]);
      done();
    });
});

查看本文https://binarapps.com/blog/test-ajax-calls-in-react-component-lifecycle/