【问题标题】:How to test react components wrapped by ThemeProvider/withStyle?如何测试由 ThemeProvider/withStyle 包裹的反应组件?
【发布时间】:2019-11-21 15:10:26
【问题描述】:

我想测试一个用 withStyle 包裹的组件,但看起来主题对象没有通过该组件。 我很好奇是否有任何好的做法可以做到这一点。

我想尝试使用createShallow() 和dive() 来访问

//GameBoard.test.js
import React from 'react';
import { createShallow } from '@material-ui/core/test-utils'
import GameBoard from './GameBoard';
import { ThemeProvider} from '@material-ui/styles';
import { createMuiTheme } from '@material-ui/core'

describe('GameBoard', () => {

  const theme = createMuiTheme({
    background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
    typography: {
      htmlFontSize: 18
    }
  });

  let shallow

  const MockTheme = ({ children }) => {
    return (
      <ThemeProvider theme={theme}>
        {children}
      </ThemeProvider>
    );
  }

  beforeAll(() => {
    shallow = createShallow()
  })



  it('renders without crashing', () => {
    const board = shallow(<MockTheme><GameBoard/></MockTheme>)
  })

  it('random answer is between 0 and 100', () => {
    const board = shallow(<MockTheme><GameBoard/></MockTheme>)
    board.find(GameBoard).dive()
    //this is what I really want to try, to access its component method:
    board.find(GameBoard).dive().instance().setConfig(0, 100)
    //expect(board.state('answer')).toBeGreaterThanOrEqual(0)
    //expect(board.state('answer')).toBeLessThanOrEqual(100)
  })
})

我的 GameBoard 组件是用

导出的
export default withStyles(styles)(GameBoard)

App.js,它的父组件


const theme = createMuiTheme({
  background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
  typography: {
    htmlFontSize: 18
  }
});

const App = () => {
  return (
    <ThemeProvider theme={theme}>
      <GameBoard/>
    </ThemeProvider>
  );
}

export default App;

样式

const styles = theme => createStyles({
  root: {
    flexGrow: 1,
    marginBottom: theme.spacing(3),
  },

})

测试结果

FAIL  src/GameBoard.test.js
  ● Console

    console.error node_modules/warning/warning.js:34
      Warning: Material-UI: the `styles` argument provided is invalid.
      You are providing a function without a theme in the context.
      One of the parent elements needs to use a ThemeProvider.

  ● GameBoard › random answer is between 0 and 100

    TypeError: theme.spacing is not a function

      4 |   root: {
      5 |     flexGrow: 1,
    > 6 |     marginBottom: theme.spacing(3),
        |                         ^
      7 |   },
      8 |   paper: {
      9 |     height: "100%",

【问题讨论】:

  • 当您使用浅层渲染时,ThemeProvider 不会真正完成提供主题的工作。您应该使用mount 而不是shallow
  • 挂载时是否可以在其子组件上使用 .instance()?

标签: javascript reactjs jestjs material-ui enzyme


【解决方案1】:

刚刚找到了一种使用mount的方法,找到它的子组件,我觉得这样就解决了问题。

describe('GameBoard', () => {

  const theme = createMuiTheme({
    background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
    typography: {
      htmlFontSize: 18
    }
  });

  let mount

  const MockTheme = ({ children }) => {
    return (
      <ThemeProvider theme={theme}>
        {children}
      </ThemeProvider>
    );
  }

  beforeAll(() => {
    mount = createMount()
  })



  it('renders without crashing', () => {
    const board = mount(<MockTheme><GameBoard/></MockTheme>)
  })

  it('random answer is between 0 and 100', () => {
    const boardWrapper = mount(<MockTheme><GameBoard/></MockTheme>)
    const board = boardWrapper.find("GameBoard").at(0)
    board.instance().setNewConfig(0, 100)
    expect(board.state('answer')).toBeGreaterThanOrEqual(0)
    expect(board.state('answer')).toBeLessThanOrEqual(100)
  })
})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-22
    • 2020-01-26
    • 2017-12-04
    • 2018-12-02
    • 2018-01-17
    • 2020-09-16
    相关资源
    最近更新 更多