Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在React with Jest中使用样式为@material ui创建手动模拟_Javascript_Reactjs_Mocking_Jestjs_Material Ui - Fatal编程技术网

Javascript 在React with Jest中使用样式为@material ui创建手动模拟

Javascript 在React with Jest中使用样式为@material ui创建手动模拟,javascript,reactjs,mocking,jestjs,material-ui,Javascript,Reactjs,Mocking,Jestjs,Material Ui,我正在尝试为@material ui/core/styles模块创建手动模拟,该模块导出名为with styles的HOC 将内联mock与jest.mock结合使用效果很好,但当我尝试将此逻辑移动到sharable\uuuuuumocks\uuuuu文件夹中时,它不再起作用 我从正在测试的文件中删除了所有不必要的代码,只保留了产生问题的两行代码: import { withStyles } from '@material-ui/core/styles'; console.log('loade

我正在尝试为
@material ui/core/styles
模块创建手动模拟,该模块导出名为
with styles
的HOC

将内联mock与
jest.mock
结合使用效果很好,但当我尝试将此逻辑移动到sharable
\uuuuuumocks\uuuuu
文件夹中时,它不再起作用

我从正在测试的文件中删除了所有不必要的代码,只保留了产生问题的两行代码:

import { withStyles } from '@material-ui/core/styles';

console.log('loaded styles:', withStyles);

export default 'hello';
测试也简化了,只是为了看看模拟是否工作,如下所示:

import test from '../test';
console.log(test);
我尝试的是在项目的根目录中创建一个
\uuu mocks\uu
文件夹,其中有
节点\u modules
文件夹

在那里,我创建了第一个名为
@materialui
的文件夹,并在其中创建了另一个名为
core
的文件夹。 在这个文件夹中,我有一个名为
styles.js
的文件,其中包含以下代码:

export const withStyles = 'hello world';
所以结构看起来像:

- __mocks__
  - @material-ui
    - core
      - styles.js
- node_modules
这是在同一测试文件中定义模拟的代码:

jest.mock('@material-ui/core/styles', () => ({
  withStyles: () => Component => props => (
    <Component
      classes=""
      {...props}
    />
  ),
}));
在我的测试文件中,它使用real
和style
,因此使用real模块。 没有使用任何模拟

如果我使用:

jest.mock('@material-ui/core/styles');
它使用jest自动生成的自动模拟(或者看起来是这样),跳过了我上面定义的模拟

关于软件包,我使用了
CRA
来引导应用程序,我目前使用的
jest
版本是20,带有
react脚本
版本1.0.17


谢谢大家的帮助

以下是您应该如何在
\uuuuuumocks\uuuuu/@material ui/core/styles.js
中使用手动模拟:

// Grab the original exports
import * as Styles from '@material-ui/core/styles';

const mockWithStyles = () => {
  console.log('withStyles being mocked'); // this shows that it works
  /**
   * Note: if you want to mock this return value to be
   * different within a test suite then use
   * the pattern defined here:
   * https://jestjs.io/docs/en/manual-mocks
   */

  return () => {}; // your mock function (adjust as needed)
  // you can also return the same implementation on certain conditions
  // return Styles.makeStyles; 
};

module.exports = { ...Styles, withStyles: mockWithStyles };
下面是我如何手动模拟
makeStyles

// Grab the original exports
// eslint-disable-next-line import/no-extraneous-dependencies
import * as Styles from '@material-ui/core/styles';
import createMuiTheme from '@material-ui/core/styles/createMuiTheme';
import options from '../../../src/themes/options';

const mockMakeStyles = func => {
  /**
   * Note: if you want to mock this return value to be
   * different within a test suite then use
   * the pattern defined here:
   * https://jestjs.io/docs/en/manual-mocks
   */

  /**
   * Work around because Shallow rendering does not
   * Hook context and some other hook features.
   * `makeStyles` accept a function as argument (func)
   * and that function accept a theme as argument
   * so we can take that same function, passing it as
   * parameter to the original makeStyles and
   * binding it with our custom theme
   */
  const theme = createMuiTheme(options);
  return Styles.makeStyles(func.bind(null, theme));
};

module.exports = { ...Styles, makeStyles: mockMakeStyles };
makeStyles
结果使用
React.useContext
,因此我们必须避免对
makeStyles
模拟
useContext
。如果在组件中首先使用
React.useContext(…)
,请使用
mockImplementationOnce
,或者在测试代码中过滤掉它,如下所示:

jest.spyOn(React, 'useContext').mockImplementation(context => {
  console.log(context);
  // only stub the response if
  if (context.displayName === 'MyAppContext') {
    return {
      auth: {},
      lang: 'en',
      snackbar: () => {},
    };
  }

  const ActualReact = jest.requireActual('react');
  return ActualReact.useContext(context);
});
在调用
createContext()
时,可能在
store.js
中添加
displayName
(标准)或任何其他自定义属性来标识上下文:

const store = React.createContext(initialState);
store.displayName = 'MyAppContext';
makeStyles
上下文显示名称将显示为
StylesContext
themeecontext
,它们的实现将保持不变以避免错误


这修复了
makeStyles
的所有模拟问题。但是我没有使用
和样式来深入了解它的结构,但是类似的逻辑应该是适用的。

我找到了在(
\uuuuuumocks\uuuu/@material ui/core/styles.js
)中手动模拟makeStyles的完美方法,方法是使用相同的原始makeStyles绑定一个动态创建的主题。这解决了
未定义主题
、测试覆盖率、通过
道具
内部
makeStyles
函数属性的未覆盖测试的所有问题。如果你仍然想要这个,我会花点时间来回答,因为它还处理
jest.spyOn(React,'useContext').mockImplementation(()=>{})
,这会使一些
useStyles
崩溃,这些
useStyles
也会在内部使用
React.useContext
,这类似于
withStyles
,但是
makeStyles
更适合于Hook,这就是我所使用的。但同样的逻辑也适用。此外,您不应该使用
jest.mock(“@materialui/core/styles”)在手动模拟中。在Manual Mock中,您必须返回您想要代替
样式的任何内容。例如,您可以只导入所有样式,准备一个
withStyles
函数并返回
{….Styles.withStyles}
以仅替换
withStyles
const store = React.createContext(initialState);
store.displayName = 'MyAppContext';