如何测试反应组件使用jest呈现列表

时间:2017-06-01 13:22:47

标签: javascript unit-testing reactjs jestjs snapshot

我试图了解单元测试的工作原理,并构建了一个小型React应用程序,用于呈现一个Pokemon列表。 我要做的是编写一个单元测试,检查列表是否正确呈现。但是,生成的快照显示它仅呈现“正在加载...”#39;在等待API响应时应该执行的文本。 我做错了什么?

PokemonList.test.js

import React from 'react';
import PokemonList from '../components/PokemonList';
import renderer from 'react-test-renderer';

describe('PokemonList component renders a list of Pokemon', () => {
    it('renders correctly', () => {
        const fetched = true;
        const loading = true;
        const species = [{
            "0": {"name": "bulbasaur"},
            "1": {"name": "ivysaur"},
            "2": {"name": "venusaur"}
        }];
        const rendered = renderer.create(
            <PokemonList fetched={fetched} loading={loading} species={species} />
        );
        expect(rendered.toJSON()).toMatchSnapshot();
    });
});

PokemonList.js

// The PokemonList component show nothing when it mounts for the first time.
// But right before it mounts to the DOM, it makes an API call to fetch the
// first 151 Pokemon for the API and then displays them using the Pokemon component.

import React from 'react';
import Pokemon from './Pokemon';

class PokemonList extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            species: [],
            fetched: false,
            loading: false,
        };
    }

    componentWillMount() {
        this.setState({
            loading: true
        });
        fetch('http://pokeapi.co/api/v2/pokemon?limit=151').then(res=>res.json())
        .then(response=>{
            this.setState({
                species: response.results,
                loading: true,
                fetched: true
            });
        });
    }

    render() {
        const {fetched, loading, species} = this.state;
        let content ;
        if (fetched) {
            content = <div className="pokemon--species--list">{species.map((pokemon, index) => <Pokemon key={pokemon.name} id={index+1} pokemon={pokemon} />)}</div>
        } else if (loading && !fetched) {
            content = <p className="loading"> Loading ...</p>
        } else {
            content = <div/>
        }
        return (
            <div>
                {content}
            </div>
        )
    }
}

export default PokemonList;

PokemonList.test.js.snap

exports[`PokemonList component renders a list of Pokemon renders correctly 1`] = `
<div>
  <p
    className="loading">
     Loading ...
  </p>
</div>
`;

1 个答案:

答案 0 :(得分:0)

你试图通过道具改变PokemonList组件中的状态,但是PokemonList不会对道具做任何事情,所以状态不会改变。我认为设置状态和测试PokemonList组件的一种方式(在我看来最简单)是Enzymeenzyme-to-json。这是一个例子:

import React from 'react';
import PokemonList from '../components/PokemonList';
// Importing shallow and toJson.
import {shallow} from "enzyme";
import toJson from "enzyme-to-json";

describe('PokemonList component renders a list of Pokemon', () => {
  it('renders correctly', () => {
    const wrapper = shallow(<PokemonList/>);
    const fetched = true;
    // You can omit setting the loading to true, because componentWillMount in PokemonList component takes care of that.
    //const loading = true;

    // I've changed your species array, that way it should work as expected.
    const species = [
      {name: "bulbasaur"},
      {name: "ivysaur"},
      {name: "venusaur"}
    ];

    wrapper.setState({
      fetched,
      species
    });

    expect(toJson(wrapper)).toMatchSnapshot();
  });
});

另外我建议在fetch中使用https。