2017-06-01 45 views
0

我想了解單元測試如何工作,並建立了一個小的React應用程序,呈現出一個口袋妖怪列表。 我想要做的是編寫一個單元測試,檢查列表是否正確渲染。但是,生成的快照顯示它只會呈現「loading ...」文本,這是在等待來自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> 
`; 
+0

'loading'和'fetched'不應該都是同一時間。數據正在被提取'loading'或'fetched' – dcodesmith

+0

@dcodesmith我試着改變這些值,但我仍然在快照中得到相同的輸出 –

+0

當你成功地獲取你的數據時,你的'loading'狀態應該是'false'而不是'真正的'因爲你完成獲取數據。解決這個問題,看看會發生什麼 – dcodesmith

回答

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(); 
    }); 
}); 

另外,我會建議使用HTTPS獲取。

+0

這工作!非常感謝: ) –

+0

@JohnThomson樂意幫忙! – Zero