Material-UIのHidden要素をテストする
個人のプロジェクトでMaterial-UIを使っているんですが、 コンポーネントがHiddenを含んでいると、テストがうまく動きません。
import * as React from 'react'; import {Hidden} from "@material-ui/core"; export const Hoge = (): JSX.Element => { return ( <div> <Hidden mdUp> <div>mdUp</div> </Hidden> <Hidden smDown> <div>smDown</div> </Hidden> </div> ) };
import React from "react"; import {render, cleanup} from '@testing-library/react' import {Hoge} from "../hoge"; afterEach(async () => { await cleanup(); }); describe('hoge', () => { describe('ある幅以上の時のレンダリング', () => { it('mdUpが表示される', () => { const {getByText} = render( <Hoge/> ); expect(getByText("mdUp")).toBeVisible() }); }); });
見つけられない...ていうかそもそもHidden要素がどっちもレンダリングされていない
TestingLibraryElementError: Unable to find an element with the text: mdUp. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.
<body>
<div>
<div />
</div>
</body>
13 | <Hoge/>
14 | );
> 15 | expect(getByText("mdUp")).toBeVisible()
| ^
16 | });
17 | });
18 | });
環境
"@material-ui/core": "^4.10.2",
"react": "^16.13.1",
"@testing-library/dom": "^7.16.3",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.3.0",
"@testing-library/user-event": "^12.0.7"
原因など
Unable to test React with Material-UI Hidden element · Issue #2179 · enzymejs/enzyme · GitHub によると、jest-domとmaterial-uiの双方に課題があるようです。 -> https://github.com/enzymejs/enzyme/issues/2179#issuecomment-528973289
対応
対応方法は2つほどあるぽいです、ここではかんたんな方を書きます。
テスト側でrenderするときにcreateMuiThemeを用いて初期の画面幅を指定するやりかたです。
import React from "react"; import {render, cleanup} from '@testing-library/react' import {createMuiTheme, MuiThemeProvider} from "@material-ui/core"; import {Hoge} from "../hoge"; afterEach(async () => { await cleanup(); }); describe('hoge', () => { describe('ある幅以上の時のレンダリング', () => { it('mdUpが表示される', () => { const theme = createMuiTheme({props: {MuiWithWidth: {initialWidth: 'sm'}}}) const {getByText} = render( <MuiThemeProvider theme={theme}> <Hoge/> </MuiThemeProvider> ); expect(getByText("mdUp")).toBeVisible() }); }); });
これで画面幅を指定して実行できます。
initialWidthをmdにするとsmDownの方の要素が表示状態になります。
おわりに
ReactでTDDでやっていくぞと思って触り始めたけどやはりUI部分はなかなか大変だなと思いつつ、Androidよりは楽かもという気持ち