材料UI +酶测试组件

时间:2018-06-18 19:35:23

标签: reactjs jestjs material-ui enzyme

我在React中有组件,我试图用Jest测试,遗憾的是测试没有通过。

组件代码:

import React, {Component} from 'react';
import ProductItem from '../ProductItem/ProductItem';
import AppBar from "@material-ui/core/es/AppBar/AppBar";
import Tabs from "@material-ui/core/es/Tabs/Tabs";
import Tab from "@material-ui/core/es/Tab/Tab";
import {connect} from 'react-redux';


class ProductsTabsWidget extends Component {

    state = {
        value: 0
    }

    renderTabs = () => {
        return this.props.tabs.map((item, index) => {
            return item.products.length > 0 ? (<Tab key={index} label={item.title}/>) : false;
        })
    }

    handleChange = (event, value) => {
        this.setState({value});
    };


    renderConentActiveTab = () => {
        if (this.props.tabs[this.state.value]) {
            return this.props.tabs[this.state.value].products.map((productIndex) => {
                return (<ProductItem key={productIndex} {...this.props.products[productIndex]} />);
            });
        }
    }

    render() {
        let tabs = null;
        let content = null;
        if (this.props.tabs) {
            tabs = this.renderTabs();
            content = this.renderConentActiveTab();
        }
        return (
            <div>
                <AppBar position="static" color="default">
                    <Tabs
                        value={this.state.value}
                        onChange={this.handleChange}
                        indicatorColor="primary"
                        textColor="primary"
                        centered
                        scrollButtons="auto"
                    >
                        {tabs}
                    </Tabs>
                </AppBar>
                <div className="productWidget">
                    <div className="wrapper">
                        {content}
                    </div>
                </div>
            </div>
        )
    }
}

const mapStateToProps = state => {
    return {
        products: state.product.products,
    }
}

export default connect(mapStateToProps)(ProductsTabsWidget);

我曾尝试为此组件编写正确的测试,代码如下:

import React from 'react';

import {configure, shallow} from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import ProductsTabsWidget from "./ProductsTabsWidget";


configure({adapter: new Adapter()});

describe('ProductsTabsWidget - component', () => {
    let wrapper;


    beforeEach(() => {
        wrapper = shallow(<ProductsTabsWidget/>);
    });

    it('renders with minimum props without exploding', () => {
        wrapper.setProps({
            tabs: [],
            products:[]
        });
        expect(wrapper).toHaveLength(1);
    });
})

但是当我正在运行测试时,我收到错误:

Test suite failed to run

    F:\PRACA\reactiveShop\node_modules\@material-ui\core\es\AppBar\AppBar.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import _extends from "@babel/runtime/helpers/builtin/extends";
                                                                                             ^^^^^^

    SyntaxError: Unexpected token import

      at new Script (vm.js:51:7)
      at Object.<anonymous> (src/components/product/ProductsTabsWidget/ProductsTabsWidget.js:3:15)

我尝试使用shallowmountrender进行测试,但没有帮助。我错过了什么?

我的应用程序是在create-react-app上创建的。

3 个答案:

答案 0 :(得分:6)

使用@material-ui时会有所不同。

您必须使用@material-ui的内置API。例如createMountcreateShallowcreateRender,以便使用酶的shallowmountrender

这些API建立在enzyme之上,因此您不能直接使用enzyme来测试@material-ui


{@ {1}}使用@ material-ui渲染的示例

Shallow

参考:Official Docs of @material-ui

答案 1 :(得分:0)

类似的事情对我有用:

import {createMount} from '@material-ui/core/test-utils';

const WrappedComponent = () => 
    <MUIThemeStuffEtc>
        <MyComponent />
    </MUIThemeStuffEtc>

const render = createMount();
const wrapper = render(<WrappedComponent />);

const state = wrapper.find(MyComponent).instance().wrappedInstance.state

答案 2 :(得分:0)

以下是从spring:formcreate-react-app的角度出发提供更完整答案的谦虚尝试。

@material-ui直接在1.文件夹中创建setupTests.js并粘贴以下代码。

src

import { configure } from "enzyme"; import Adapter from "enzyme-adapter-react-16"; configure({ adapter: new Adapter() }); 以下是使用2.组件的React无状态组件。

material-ui

请注意,在上述组件中,该组件希望父组件传递import React from "react"; import TextField from "@material-ui/core/TextField"; const SearchField = props => ( <TextField InputProps={{ disableUnderline: true }} fullWidth placeholder={props.placeholder} onChange={props.onChange} /> ); export default SearchField; placeholder事件处理程序的道具

onChange()在上述组件的测试案例中,我们可以用3.建议的方式或material-ui的方式编写。两者都可以。

pure enzyme样式

Pure Enzyme

import React from "react"; import { mount } from "enzyme"; import TextField from "@material-ui/core/TextField"; import SearchField from "../SearchField"; describe("SearchField Enzyme mount() ", () => { const fieldProps = { placeholder: "A placeholder", onChange: jest.fn() }; const Composition = props => { return <SearchField {...fieldProps} />; }; it("renders a <TextField/> component with expected props", () => { const wrapper = mount(<Composition />); expect(wrapper.childAt(0).props().placeholder).toEqual("A placeholder"); expect(wrapper.childAt(0).props().onChange).toBeDefined(); }); it("should trigger onChange on <SearchField/> on key press", () => { const wrapper = mount(<Composition />); wrapper.find("input").simulate("change"); expect(fieldProps.onChange).toHaveBeenCalled(); }); it("should render <TextField />", () => { const wrapper = mount(<Composition />); expect(wrapper.find(TextField)).toHaveLength(1); expect(wrapper.find(TextField).props().InputProps.disableUnderline).toBe( true ); }); }); 风格

Material UI

import React from "react"; import { createMount } from "@material-ui/core/test-utils"; import TextField from "@material-ui/core/TextField"; import SearchField from "../SearchField"; describe("SearchField", () => { let mount; const fieldProps = { placeholder: "A placeholder", onChange: jest.fn() }; beforeEach(() => { mount = createMount(); }); afterEach(() => { mount.cleanUp(); }); it("renders a <TextField/> component with expected props", () => { const wrapper = mount(<SearchField {...fieldProps} />); expect(wrapper.props().placeholder).toEqual("A placeholder"); expect(wrapper.props().onChange).toBeDefined(); }); it("should trigger onChange on <SearchField/> on key press", () => { const wrapper = mount(<SearchField {...fieldProps} />); wrapper.find("input").simulate("change"); expect(fieldProps.onChange).toHaveBeenCalled(); }); }); 您收到的错误是由于5.没有机会处理您的文件。 babel希望您运行类似create-react-app而不是类似yarn run test的测试。如果您使用后一个jest your/test/file.js,则不会是babel

如果您想使用employed运行文件,则必须编写一个jest文件或在jest.config.js文件中配置jest才能使用package.json + babel-jest可以在玩笑尝试执行测试之前转换代码。

昨天我第一次尝试使用other babel dependencies时是在同一条船上,来到这里以获得更完整的答案。