Material ui 使用钩子API和;酶浅涂

Material ui 使用钩子API和;酶浅涂,material-ui,enzyme,react-hooks,Material Ui,Enzyme,React Hooks,最新版本的Material UI现在有了一个钩子替代品,用于设置组件的样式,而不是HoC。所以不是 const styles = theme => ({ ... }); export const AppBarHeader = ({ classes, title }) => ( ... ); export default withStyles(styles)(AppBarHeader); 您可以选择这样做: const useStyles = makeStyles(them

最新版本的Material UI现在有了一个钩子替代品,用于设置组件的样式,而不是HoC。所以不是

const styles = theme => ({
  ...
});

export const AppBarHeader = ({ classes, title }) => (
  ...
);
export default withStyles(styles)(AppBarHeader);
您可以选择这样做:

const useStyles = makeStyles(theme => ({
  xxxx
}));

const AppBarHeader = ({ title }) => {
  const classes = useStyles();
  return (
    ....
  )
};

export default AppBarHeader;
在某些方面,这是更好的,但是对于所有钩子,您不能再向组件注入“存根”依赖项。之前,对于酶的测试,我只测试了非风格的成分:

describe("<AppBarHeader />", () => {
  it("renders correctly", () => {
    const component = shallow(
      <AppBarHeader title="Hello" classes="{}" />
    );
    expect(component).toMatchSnapshot();
  });
});
因为你总是需要一个合适的提供者。我可以去把这个包起来:

describe("<AppBarHeader />", () => {
  it("renders correctly", () => {
    const component = shallow(
      <ThemeProvider theme={theme}>
        <AppBarHeader title="Hello" classes="{}" />
      </ThemeProvider>
    ).dive();
    expect(component).toMatchSnapshot();
  });
});
描述(“,()=”>{
它(“正确渲染”,()=>{
常数分量=浅(
).潜水();
expect(component.toMatchSnapshot();
});
});

但这似乎不再呈现组件的子级(即使使用了俯冲调用)。人们是如何做到这一点的?

编辑:根据下面的评论,此实现存在一些时间问题。考虑使用RAMP进行测试,而不是进行浅层测试,或者使用<代码>使用样式 尝试存根
makeStyles
时出现了一些问题,因为似乎MUI已将其设置为只读。因此,我没有在每个组件中创建一个
useStyles
钩子,而是创建了自己的自定义
useStyles
钩子来调用
makeStyles
。通过这种方式,我可以存根我的
useStyles
hook进行测试,对代码流的影响最小

// root/utils/useStyles.js
// My custom useStyles hook

import makeStyles from '@material-ui/styles/makeStyles';

export const useStyles = styles => makeStyles(theme => styles(theme))();
这几乎就像使用
和样式一样
HOC

// root/components/MyComponent.js
import React from 'react';
import { useStyles } from '../util/useStyles';

// create styles like you would for withStyles
const styles = theme => ({
  root: {
    padding: 0,
  },
});

export const MyComponent = () => {
  const classes = useStyles(styles);
  return(
    </>
  );
}
//root/components/MyComponent.js
从“React”导入React;
从“../util/useStyles”导入{useStyles};
//创建与withStyles类似的样式
常量样式=主题=>({
根目录:{
填充:0,
},
});
导出常量MyComponent=()=>{
常量类=使用样式(样式);
返回(
);
}
//root/component/MyComponent.spec.js
从“/MyComponent”导入{MyComponent};
从“酶”导入{shall};
从“sinon”导入{stub};
描述('render',()=>{
它('应该呈现',()=>{
让我们用浴缸;
useStylesStub=存根(挂钩,“useStyles”);
返回({});
常量包装器=浅();
控制台日志(“利润”);
});
});

这是目前我能想到的最好的方法,但总是对建议持开放态度。

答案似乎是(a)不要进行浅层渲染,(b)使用反应测试库而不是酶。这种方法有问题
makeStyles
旨在为每个样式对象调用一次,但使用您的方法,它将为每个渲染调用一次。每个渲染将使用由
makeStyles
返回的自定义挂钩的新版本。这也会对生成的样式表的顺序产生负面影响(请参见我的答案以获取解释)。与使用此方法相比,您最好使用
with style
。也请参阅我的答案,以进一步了解此方法将导致的问题。感谢更新,我担心这会导致问题UseEffect没有正确的时间来管理此问题。我的建议是改变测试方法,不要像@JamesCrowley在他的评论中提到的那样使用浅层渲染,而不要在代码中使用奇怪的变通方法。
makeStyles
的计时仍将关闭。要使父组件样式和子组件样式之间的交互正常工作,应在导入组件时而不是渲染组件时调用
makeStyles
// root/components/MyComponent.js
import React from 'react';
import { useStyles } from '../util/useStyles';

// create styles like you would for withStyles
const styles = theme => ({
  root: {
    padding: 0,
  },
});

export const MyComponent = () => {
  const classes = useStyles(styles);
  return(
    </>
  );
}
// root/component/MyComponent.spec.js
import { MyComponent } from './MyComponent';
import { shallow } from 'enzyme';
import { stub } from 'sinon';

describe('render', () => {
  it('should render', () => {
    let useStylesStub;
    useStylesStub = stub(hooks, 'useStyles');
    useStylesStub.returns({ });
    const wrapper = shallow(<MyComponent />);
    console.log('profit');
  });
});