如何测试由ThemeProvider / withStyle包装的组件?

时间:2019-07-11 20:39:17

标签: javascript reactjs jestjs material-ui enzyme

我想测试一个由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%",

1 个答案:

答案 0 :(得分:0)

我只是找到了一种使用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)
  })
})