ReactJS测试条件渲染(快照)

时间:2018-08-21 19:57:03

标签: reactjs unit-testing jestjs enzyme snapshot

我正在尝试测试我的ReactJS应用程序,但是有一个问题。 我有一个以某种方式为应用程序的第一页呈现的标题,并且此标题将在所有其他页面中更改。我正在使用react-router-dom中的当前位置来管理更改。 我不知道如何根据URL测试标题更改。 现在,我正在测试文件中进行基本操作:

import React from 'react';
import { shallow } from 'enzyme';
import HeaderSto from './HeaderSto';
import '../../setupTests';

describe("HeaderSto", () => {

    it("should render my component", () => {
        process.env.REACT_APP_MERCHANT = "merchant";
        const wrapper = shallow(<HeaderSto />);
        expect.anything(wrapper);
    });

    it("should render LandingPage header layout", () => {
        process.env.REACT_APP_MERCHANT = "merchant";
        window.location.assign = jest.fn();
        const tree = shallow(<HeaderSto />);
        expect(tree).toMatchSnapshot();
    });
});

和组件

import React from 'react';
import { Row, Col } from 'antd';

class HeaderSto extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            CurrentRoute: ""
        };
    }

    componentDidMount() {
        this.setState({
            CurrentRoute: this.props.CurrentRoute
        });
    }

    componentWillReceiveProps(nextProps) {
        this.setState({
            CurrentRoute: nextProps["CurrentRoute"]
        });
    }

    renderGeneralHeader() {

        return(<div>Hi</div>);
    }

    renderLandingPageHeader() {

        const logo = require("../../images/" + process.env.REACT_APP_MERCHANT + "/" + process.env.REACT_APP_MERCHANT + "_logo.svg");
        return (
            <div>
                <Row>
                    <Col className="header-merchant-logo-div" xs={{span: 18, offset: 3}} sm={{span: 18, offset: 3}} md={{span: 18, offset: 3}} lg={{span:4, offset: 1}} xl={{span:4, offset: 1}}>
                        <img className="header-merchant-logo" src={logo} alt="MerchantLogo"/>
                    </Col>
                </Row>
            </div>
        );
    }

    render() {
        return (
            <div>
                {this.state.CurrentRoute === "/" ? this.renderLandingPageHeader() : this.renderGeneralHeader()}
            </div>
        );
    }
}

export default HeaderSto;

我必须模拟位置(应该很简单),但我不明白如何指定快照以取决于该位置是否不同...

我想我已经解释了一切,如有需要,随时询问更多细节。

感谢您的帮助。 祝你有美好的一天

2 个答案:

答案 0 :(得分:1)

嗨,如果您正在按照自己的目标学习单元测试,请多谢。 请记住,Jest有两种类型的测试SnapShot和组件行为测试。我们对快照进行更多测试,例如“我们如何构造组件”。如果对jsx结构进行了任何更改,则该快照不应与以前的快照匹配。

在您的情况下,如果您看到覆盖率报告,则HeaderSto中有两个分支。您需要确保同时测试两种情况,以确保 100%。一次通过“ /”,另一次通过其他途径来满足这两个条件。

这就是我们进行快照测试的方式:

import renderer from 'react-test-renderer';

it('renders correctly', () => {
  const tree = renderer.create(
    <HeaderSto />
  ).toJSON();
  expect(tree).toMatchSnapshot();
});

已编辑,让我们以一个示例来区分快照测试和浅/挂载测试策略。

我们有一个应用程序组件:

class App extends Component {
  render() {
    return (
      <div className="App">
        <Header />
        <p className="App-intro" onClick={this.handleClick}>
          {data.appName}.
        </p>
      </div>
    );
  }
}

SnapShot 的测试结果如下:

exports[`renders without crashing 1`] = `
<div
  className="App"
>
  <Header />
  <p
    className="App-intro"
    onClick={[Function]}
  >
    To get started, edit 
    <code>
      src/App.js
    </code>
     and save to reload.
  </p>
</div>
`;

渲染将告诉我们组件的行为方式:  我们将模拟data.appName和onClick方法,因为我们的App期望一个道具appName和aslo我们需要测试它的句柄点击,因此我们模拟了它们两者:

const data = {
 appName: 'My App'
}
describe('HandleClick on P event success', () => {
 it('handleClick click invokes without throwing an error', () => {
    const handleClick = jest.fn();
    const wrapper = shallow(<App
      handleClick={handleClick}
       />);
    wrapper.find('.app').simulate('click');
    expect(handleClick).toHaveBeenCalled();
  });
});

随时分享任何想法。很高兴为您提供帮助。

答案 1 :(得分:0)

我看不到您在哪里使用位置函数,似乎CurrentRoute只是通过道具传递的。因此,只需将其通过您的测试即可:

it("should render LandingPage header layout", () => {
    process.env.REACT_APP_MERCHANT = "merchant";
    const tree = shallow(<HeaderSto />);
    expect(tree).toMatchSnapshot();
});

it("should render LandingPage header layout", () => {
    process.env.REACT_APP_MERCHANT = "merchant";
    const tree = shallow(<HeaderSto currentRoute="/some-other-path" />);
    expect(tree).toMatchSnapshot();
});