個人のプロジェクトで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よりは楽かもという気持ち