2016-08-25 217 views
4

我正在使用庫React-Reponsive。 https://github.com/contra/react-responsive如何使用酶測試React-Responsive組件?

我竭力要弄清楚如何測試嵌套在陣營響應媒體查詢組件組成:

export default class AppContainer extends React.Component { 
    render(){ 
    return(
     <MediaQuery minDeviceWidth={750}> 
     <Header /> 
     </MediaQuery> 
    ); 
    } 
} 

-

describe("AppContainer",() => { 
    let App; 
    let wrapper; 
    beforeEach(() => { 
    wrapper = mount(<Provider store={store}><AppContainer location={location} /></Provider>); 
    App = wrapper.find(AppContainer); 

    }); 
    it('to have a <Header /> component',() => { 
    console.log(App.debug()); 
    expect(App.find(Header)).to.have.length(1); 
    }); 
} 

測試結果:

1) AppContainer to have a <Header /> component: 
AssertionError: expected { Object (component, root, ...) } to have a length of 1 but got 0 

輸出的相關部分的console.log是:

<MediaQuery minDeviceWidth={750} values={{...}} /> 

指示標頭確實沒有出現在渲染樹中。但是,如果我移除MediaQuery並使Header成爲測試通過的AppContainer的直接子元素。

我想這不是一個錯誤,因爲我對酶和測試組件一般都很陌生。任何幫助或例子,將不勝感激。

請注意:我對這個組件的其他測試通過的很好。我相信進口和設置都是正確的。

+0

豈不是'期待(App.find(MediaQuery))來。有。(1);' – vijayst

+0

是的,它可以用於測試媒體查詢,但我正在尋找的是如何在這種情況下測試標題 –

回答

1

問題在於Media Query正在尋找window.matchMedia,其中jsdom未定義。

在這種情況下,我需要使用服務器端渲染實施。然而,這將需要寬度的靜態值,這會打破響應。

我的解決方案是在測試虛擬DOM上設置一個全局變量。

window.testMediaQueryValues = {width:740}; 

然後MediaQuery可以訪問他們,如果他們在那裏:

<MediaQuery maxWidth={smallViewMaxWidth} values={window.testMediaQueryValues}> 

在時未設置變量的情況下,空值被忽略,組件呈現如常。

非常感謝@Contra對他的幫助和超級圖書館

+1

也許反應響應是不同的,當你寫這個,但截至今天,在瀏覽器上下文中不使用'values'。所以你不需要全局測試值。相反,您可以傳遞一個用於保存目的的道具。 –

+0

@ rodrigo-silveira你能詳細說明一下嗎?不知道你的意思是傳遞一個道具來達到同樣的目的 – tscizzle

+0

我想我的意思是你的組件可以使用一個可選的道具,比如'width'或'displayMode',它可以用來決定哪個子組件渲染,而不是依靠窗口狀態來告訴你視窗的寬度。 –

0

嘗試在嘲笑你的單元測試的反應響應依賴。使用Webpack,我使用inject-loader來爲模塊注入測試依賴關係。你可以使用「inject-loader」導入你的組件並傳遞你想要覆蓋的依賴關係。

例子:

import YourComponentInjector from 'inject-loader!../YourComponent.jsx'; 

然後

class MediaQueryDesktopMock extends React.Component { 
    render() { 
     const {minDeviceWidth, children} = this.props; 
     if(minDeviceWidth === 765) { 
     return (<div>{children}</div>) 
     } 
     return <span/>; 
    } 
    } 
    let YourComponentMock = YourComponentInjector({ 
    'react-responsive': MediaQueryDesktopMock 
    }); 

那麼你可以測試特定媒體的查詢