gpt4 book ai didi

javascript - enzyme 测试认证高阶组件(HOC)

转载 作者:数据小太阳 更新时间:2023-10-29 04:39:52 25 4
gpt4 key购买 nike

我创建了一个高阶组件/组合组件,以确保在加载组件之前对用户进行身份验证。这是非常基本的,但我在测试它时遇到了一些麻烦。我想测试以下几点,这与我在其他地方已经进行的测试类似:

  • 呈现组件(我通常通过查找特定于组件的 className 来检查)
  • 有正确的props(在我的例子中是authenticated)
  • 如果已通过身份验证,则呈现包装组件;如果未通过身份验证,则呈现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);
}

我正在使用 enzymejest 进行测试,但在我的测试期间还没有找到成功呈现 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 并将其导出为命名导出。你可以独立于 connect 测试它,就像你测试所有其他组件一样:

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 - enzyme 测试认证高阶组件(HOC),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41736763/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com