开发者问题收集

使用 Enzyme 测试具有 JSS 注入样式的反应组件

2017-07-23
1868

我有一个 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. 访问状态 (和其他组件特定功能)

当我在套件中 shallowmount 该作曲家时,我当然无法访问它的状态,因为它不再是我的组件,而是它周围的新东西。

例如此代码会给出错误:

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 }

这也不会让我访问 propsrefs 等。

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 和其他内容?

谢谢!

2个回答

以下是我测试组件时要做的事情

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 库中阅读更多相关信息。这是一个快速 示例

mahad
2019-01-28
  1. 它与 JSS 没有特别关系。任何 HOC 都会包装您的组件。理想情况下,您不会直接测试组件的任何内部结构。

    • 组件公共 API 是 props,使用它们以特定状态渲染您的组件,并使用浅层渲染器验证渲染的输出。

    • 对于某些边缘情况,如果第一种和首选方式不可行,您可以直接访问内部组件并直接访问您需要的任何内容。您将必须模拟 HOC 会为您传递的 props。

const StyledComponent = injectSheet(styles)(InnerComponent)
console.log(StyledComponent.InnerComponent) 
  1. 如果您的组件依赖于主题,则必须始终提供主题提供程序。
Oleg Isonen
2017-07-23