javascript – 酶测试认证高阶组件(HOC)

前端之家收集整理的这篇文章主要介绍了javascript – 酶测试认证高阶组件(HOC)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我创建了一个高阶组件/组合组件,以确保在加载组件之前对用户进行身份验证.这是非常基本的,但我在测试它时遇到了一些麻烦.我想测试下面的几点,这与我在其他地方已有的测试类似:

>渲染组件(我通常通过查找特定于组件的className来检查)
>有正确的道具(在我的情况下验证)
>如果经过身份验证,则呈现包装的Component,否则呈现null

HOC:

import React from 'react';
import { connect } from 'react-redux';
import { createStructuredSelector } from 'reselect';

import { makeSelectAuthenticated } from 'containers/App/selectors';

export default function RequireAuth(ComposedComponent) {
  class AuthenticatedComponent extends React.Component {
    static contextTypes = {
      router: React.PropTypes.object,}

    static propTypes = {
      authenticated: React.PropTypes.bool,}

    componentWillMount() {
      if (!this.props.authenticated) this.context.router.push('/');
    }

    componentWillUpdate(nextProps) {
      if (!nextProps.authenticated) this.context.router.push('/');
    }

    render() {
      return (
        <div className="authenticated">
          { this.props.authenticated ? <ComposedComponent {...this.props} /> : null }
        </div>
      );
    }
  }

  const mapStateToProps = createStructuredSelector({
    authenticated: makeSelectAuthenticated(),});

  return connect(mapStateToProps)(AuthenticatedComponent);
}

我正在使用酶和jest进行测试,但是在我的测试中没有找到成功渲染HOC的方法.

有任何想法吗?

解决方案谢谢以下答案:

import React from 'react';
import { shallow,mount } from 'enzyme';
import { Provider } from 'react-redux';

import { AuthenticatedComponent } from '../index';

describe('AuthenticatedComponent',() => {
  let MockComponent;

  beforeEach(() => {
    MockComponent = () => <div />;
    MockComponent.displayName = 'MockComponent';
  });

  it('renders its children when authenticated',() => {
    const wrapper = shallow(
      <AuthenticatedComponent
        composedComponent={MockComponent}
        authenticated={true}
      />,{ context: { router: { push: jest.fn() } } }
    );

    expect(wrapper.find('MockComponent').length).toEqual(1);
  });

  it('renders null when not authenticated',() => {
    const wrapper = shallow(
      <AuthenticatedComponent
        composedComponent={MockComponent}
        authenticated={false}
      />,{ context: { router: { push: jest.fn() } } }
    );

    expect(wrapper.find('MockComponent').length).toEqual(0);
  });
});

解决方法

这里的“棘手”部分是你的HOC返回一个连接组件,这使得测试更难,因为你有两层浅层渲染(连接组件和实际组件),你必须模拟redux存储.

相反,您可以预先定义AuthenticatedComponent并将其导出为命名导出.您可以像测试其他所有组件一样独立于连接测试它:

export class AuthenticatedComponent extends React.Component {
  static contextTypes = {
    router: React.PropTypes.object,}

  static propTypes = {
    authenticated: React.PropTypes.bool,composedComponent: React.PropTypes.any.isrequired,}

  componentWillMount() {
    if (!this.props.authenticated) this.context.router.push('/');
  }

  componentWillUpdate(nextProps) {
    if (!nextProps.authenticated) this.context.router.push('/');
  }

  render() {
    const ComposedComponent = this.props.composedComponent;
    return (
      <div className="authenticated">
        { this.props.authenticated ? <ComposedComponent {...this.props} /> : null }
      </div>
    );
  }
}

export default function RequireAuth(ComposedComponent) {
  const mapStateToProps = () => {
    const selectIsAuthenticated = makeSelectAuthenticated();
    return (state) => ({
      authenticated: selectIsAuthenticated(state),composedComponent: ComposedComponent,});
  };

  return connect(mapStateToProps)(AuthenticatedComponent);
}

示例测试:

import React from 'react';
import { shallow,mount } from 'enzyme';
import { Provider } from 'react-redux';
import configureStore from 'redux-mock-store';
import RequireAuth,{ AuthenticatedComponent } from '../';

const Component = () => <div />;
Component.displayName = 'CustomComponent';

const mockStore = configureStore([]);

describe.only('HOC',() => {
  const RequireAuthComponent = RequireAuth(Component);
  const context = { router: { push: jest.fn() } };
  const wrapper = mount(
    <Provider store={mockStore({})}>
      <RequireAuthComponent />
    </Provider>,{
      context,childContextTypes: { router: React.PropTypes.object.isrequired },}
  );
  it('should return a component',() => {
    expect(wrapper.find('Connect(AuthenticatedComponent)')).toHaveLength(1);
  });
  it('should pass correct props',() => {
    expect(wrapper.find('AuthenticatedComponent').props()).toEqual(
      expect.objectContaining({
        authenticated: false,composedComponent: Component,})
    );
  });
});

describe('rendering',() => {
  describe('is authenticated',() => {
    const wrapper = shallow(
      <AuthenticatedComponent
        composedComponent={Component}
        authenticated
      />,{ context: { router: { push: jest.fn() } } }
    );
    it('should render the passed component',() => {
      expect(wrapper.find('CustomComponent')).toHaveLength(1);
    });
  });
  describe('is not authenticated',() => {
    const wrapper = shallow(
      <AuthenticatedComponent
        composedComponent={Component}
        authenticated={false}
      />,{ context: { router: { push: jest.fn() } } }
    );
    it('should not render the passed component',() => {
      expect(wrapper.find('CustomComponent')).toHaveLength(0);
    });
  });
});

猜你在找的JavaScript相关文章