使用 Enzyme 测试具有 JSS 注入样式的反应组件
我有一个 React 组件。假设是 Todo
import React, { Component } from 'react';
import injectSheet from 'react-jss';
class Todo extends Component {
// methods that incl. state manipulation
render() {
const { classes } = this.props;
return (
<div className={classes.container}>
<WhateverElse />
</div>
);
}
}
export default injectSheet(Todo);
我想用 Enzyme 测试它。它有两个问题。
1. 访问状态 (和其他组件特定功能)
当我在套件中
shallow
或
mount
该作曲家时,我当然无法访问它的状态,因为它不再是我的组件,而是它周围的新东西。
例如此代码会给出错误:
it('should have state updated on handleAddTodo', () => {
const todo = shallow(<Todo />);
const length = todo.state('todos').length;
});
它当然会说
TypeError: Cannot read property 'length' of undefined
因为状态不是我期望的,但是:
{ theme: {}, dynamicSheet: undefined }
这也不会让我访问
props
、
refs
等。
2. 主题提供程序的问题
像这样为项目提供一些默认颜色:
import React, { Component } from 'react';
import Colors from './whatever/Colors';
class App extends Component {
render() {
return (
<ThemeProvider theme={Colors}>
<WhateverInside />
</ThemeProvider>
);
}
}
当然,在运行测试时,它会给出错误
[undefined] 请使用 ThemeProvider 以便能够使用 WithTheme
。
所以我的问题如下。有没有办法在“一个地方”解决这个问题。我怎样才能让 Enzyme 不依赖于我的组件所包装的内容?
如果不能,那么如果将 ThemeProvider 功能传递给我正在测试的组件,我该如何解决这个问题? 我怎样才能访问包装组件的状态、ref、props 和其他内容?
谢谢!
以下是我测试组件时要做的事情
import React, { Component } from 'react';
import injectSheet from 'react-jss';
const styles = {};
class Todo extends Component {
// methods that incl. state manipulation
render() {
const { classes } = this.props;
return (
<div className={classes.container}>
<WhateverElse />
</div>
);
}
}
export { styles, Todo as TodoCmp }
export default injectSheet(styles)(Todo);
在测试文件中,我会添加以下内容:
import { theme } from 'your-theme-source';
const mockReducer = (prev, curr) => Object.assign({}, prev, { [curr]: curr });
const coerceStyles = styles =>
typeof styles === 'function' ? styles(theme) : styles;
const mockClasses = styles =>
Object.keys(coerceStyles(styles)).reduce(mockReducer, {});
import {TodoCmp, styles} from 'your-js-file';
// then test as you'd normally.
it('should blah blah', () => {
const classes = mockClasses(styles);
const todo = shallow(<Todo classes={classes} />);
const length = todo.state('todos').length;
})
请在测试目录中的 nordnet-ui-kit 库中阅读更多相关信息。这是一个快速 示例
-
它与 JSS 没有特别关系。任何 HOC 都会包装您的组件。理想情况下,您不会直接测试组件的任何内部结构。
-
组件公共 API 是 props,使用它们以特定状态渲染您的组件,并使用浅层渲染器验证渲染的输出。
-
对于某些边缘情况,如果第一种和首选方式不可行,您可以直接访问内部组件并直接访问您需要的任何内容。您将必须模拟 HOC 会为您传递的 props。
-
const StyledComponent = injectSheet(styles)(InnerComponent)
console.log(StyledComponent.InnerComponent)
- 如果您的组件依赖于主题,则必须始终提供主题提供程序。