2017-08-07 87 views
4

有幾個material-ui組件不會在父組件放置位置的同一位置呈現結果。其中,我們有DialogMenuReact,Jest和Material-UI:如何測試在模式或彈出窗口中呈現的內容

這使得它顯然不可能以測試與安裝在它的一些父組件一jest.js包裝其內容的存在。

例如獲得以下幾方面組成:

class DropdownMenu extends React.Component { 
    onButtonClick = (e) => { 
    this.setState({ open: true, anchorEl: e.currentTarget }); 
    } 

    render() { 
    return (
     <div> 
     <Button onClick={this.onButtonClick}>Menu</Button> 
     <Menu 
      open={this.state.open} 
      onRequestClose={() => this.setState({ open: false })} 
     > 
      <MenuItem label="Home" /> 
      <MenuItem label="Sign in" /> 
     </Menu> 
     </div> 
    ); 
    } 
} 

此測試失敗,即使它應該直觀地工作:

it('renders some menu items',() => { 
    const wrapper = mount(<AppMenu />); 
    expect(wrapper).toContainReact(<MenuItem label="Home" />); 
}); 

這是失敗的玩笑的輸出:

renders some menu items 

Expected <AppMenu> to contain <withStyles(MenuItem) className="MenuItem" component={{...}} to={{...}}>Home</withStyles(MenuItem)> but it was not found. 
HTML Output of <AppMenu>: 
<div><button tabindex="0" class="MuiButtonBase-root-3477017037 MuiButton-root-3294871568 MuiButton-flatContrast-53993421" type="button" role="button" aria-owns="simple-menu" aria-haspopup="true"><span class="MuiButton-label-49836587">Menu</span><span class="MuiTouchRipple-root-3868442396"></span></button><!-- react-empty: 5 --></div> 

正如你所看到的,它就像是所有渲染的是<Button>。事實上,當您在瀏覽器中呈現上述組件時,並且展開菜單並檢查它的菜單項元素時,它們會呈現在DOM中的其他位置,而不是在按鈕出現的位置或其附近。它們實際上在文檔的<body>元素下直接在div <body><div data-mui-portal="true"> ... </div>內部呈現。

那麼如何測試這個菜單內容呢?

回答

0

Menu將不會被渲染,直到狀態發生變化,所以你可以在Button模擬點擊,讓其處理setState,觸發重新呈現,並找到具體MenuItem

此外,這大概可以完全不用安裝完成:

it('renders some menu items',() => { 
    const wrapper = shallow(<AppMenu />); 

    // find the Menu Button 
    const button = wrapper.findWhere(node => node.is(Button) && n.prop('children') === 'Menu'); 

    // simulate a click event so that state is changed 
    button.simulate('click'); 

    // find the Home MenuItem 
    const menuItem = wrapper.findWhere(node => node.is(MenuItem) && n.prop('label') === 'Home'); 

    // make sure it was rendered 
    expect(menuItem.exists()).toBe(true); 
});