2017-07-07 30 views
6

我使用的是Enzyme,我們實際上可以使用文檔中給出的example組件作爲我的問題的基礎。如何訪問由HOC包裝的嵌套React組件的狀態?

我們假設這個<Foo />組件使用了ReactRouter中的<Link>組件,因此我們需要將它包裝在<MemoryRouter>中進行測試。

這裏存在問題。

it('puts the lotion in the basket',() => { 
    const wrapper = mount(
    <MemoryRouter> 
     <Foo /> 
    </MemoryRouter> 
) 

    wrapper.state('name') // this returns null! We are accessing the MemoryRouter's state, which isn't what we want! 
    wrapper.find(Foo).state('name') // this breaks! state() can only be called on the root! 
}) 

因此,在使用<MemoryRouter>時,不完全確定如何訪問本地組件狀態。

也許我正在進行一個無知的測試?試圖在測試中獲取/設置組件狀態不良實踐?我無法想象它是如何,因爲酶有獲取/設置組件狀態的方法。

只是不確定應該如何訪問包裝在<MemoryRouter>中的組件的內部。

任何幫助將不勝感激!

+0

相關:https://stackoverflow.com/questions/42245215/how-to-test-child -component-方法與 - 酶 – indiesquidge

回答

5

因此,看起來酶的latest release有一個潛在的修復這個問題的訪問狀態的子組件。

比方說,我們有<Foo>(注意使用做出反應路由器<Link>)的

class Foo extends Component { 
    state = { 
    bar: 'here is the state!' 
    } 

    render() { 
    return (
     <Link to='/'>Here is a link</Link> 
    ) 
    } 
} 

注:下面的代碼僅在酶V3可用。

重溫測試代碼,我們現在能夠寫出下面的

it('puts the lotion in the basket',() => { 
    const wrapper = mount(
    <MemoryRouter> 
     <Foo /> 
    </MemoryRouter> 
) 

    expect(wrapper.find(Foo).instance().state).toEqual({ 
    bar: 'here is the state!' 
    }) 
}) 

使用wrapper.find(Child).instance()我們能夠訪問Child的狀態,即使它是一個嵌套的組件。在之前的Enzyme版本中,我們只能在根上訪問instance。您也可以撥打Child包裝上的setState功能!

我們可以使用一個類似的模式與我們的淺渲染測試

it('puts the lotion in the basket shallowly',() => { 
    const wrapper = shallow(
    <MemoryRouter> 
     <Foo /> 
    </MemoryRouter> 
) 

    expect(wrapper.find(Foo).dive().instance().state).toEqual({ 
    bar: 'here is the state!' 
    }) 
}) 

注意在淺水測試使用dive,可單,非DOM節點上運行,並且將返回節點,淺呈現。


參考文獻: