2017-08-11 50 views
1

我有一個任務來測試React組件,它依賴於BrowserRouter組件,它位於上層的某處。據我所知BrowserRouter傳遞路由對象到任何孩子,孫子等道具Jest Enzyme setState of memoryRouter dependent

組件:

import React, { Component } from 'react'; 
import Program from './Program'; 

export default class Programs extends Component { 
    constructor() { 
    super(); 
    this.state = { 
     programs: [ 
     /** example */ 
     { id: 10, name: 'Golden Knights' }, 
     { id: 20, name: 'Silver Lords' }, 
     { id: 30, name: 'Wooden Kings' }, 
     ], 
    }; 
    } 

    render() { 
    const { programs } = this.state; 
    return (
     <ul className="programs">{/*<-- add class "att-programs"*/} 
     { 
      programs.map(
      program => <Program 
       key={program.id} 
       program_id={program.id} 
       program_name={program.name} 
      />, 
     ) 
     } 
     </ul> 
    ); 
    } 
} 

當我嘗試獨立測試這個組件,我得到一個錯誤:Cannot read property 'route' of undefined。要解決這個問題,我總結我的元素爲MemoryRouter分量和我的測試看起來如下:

import React from 'react'; 
import renderer from 'react-test-renderer'; 
import { mount, shallow } from 'enzyme'; 
import { MemoryRouter } from 'react-router-dom'; 

import Programs from '../../src/components/Programs'; 

describe('<Programs />',() => { 
    it('Renders list for any child from state',() => { 

    const wrapper = mount(<MemoryRouter><Programs /></MemoryRouter>); 
    const programs = wrapper.find(Programs); 
    expect(programs.length).toBe(1); 
    programs.setState({ 
     programs: [ 
     { id: 1, name: 'qwe' }, 
     { id: 2, name: 'asd' }, 
     { id: 3, name: 'zxc' }, 
     ], 
    }); 

    expect(wrapper.find('li').length).toBe(3); 
    expect(wrapper.find('a[href="/player/1"]').length).toBe(1); 
    }); 
}); 

現在我有一個問題:ReactWrapper::setState() can only be called on the root

請幫我找出我怎麼嘲笑路由器,但留下能在測試組件上定義setState

+1

您是否想過在其他地方維護該狀態(例如Redux)?這種方式將作爲屬性傳遞到您的組件 - > 100%可測試。 – luboskrnac

回答

2

我建議不要直接更新組件的內部狀態。喲是以某種方式來操縱這個狀態的方法(或者你正在計劃)。所以在測試中使用這些機制。例如。您可能需要考慮通過wrapper.simulate("click")單擊按鈕並更改狀態。之後,您可以驗證狀態轉換是否正確。

+0

從狀態轉移到道具幫助!謝謝! – zeliboba