【发布时间】:2018-08-17 03:45:58
【问题描述】:
在我正在开发的 React 应用程序中,我将各种组件包装在我编写的 HOC 中,以执行诸如检查身份验证之类的操作。我想知道我的做法是好是坏。 HOC 的工作与预期的一样,但我想知道我是否正在做一些不太好的事情。这是一个例子:
如果用户去 /profile,组件 ProfilePage.js 被渲染:
import React from 'react';
import Profile from './Profile';
import withLogin from './hoc/withLogin';
import { connect } from 'react-redux';
export const ProfilePage = props => <div> <Profile /> </div>
const mapStateToProps = ({ auth }) => ({ auth });
export default connect(mapStateToProps)(withLogin(ProfilePage));
这是Profile.js:
import React from 'react';
import { connect } from 'react-redux';
import ProfileForm from './ProfileForm';
export const Profile = props => {
const render = () => {
return (
<div>
<h1>Profile component</h1>
<ProfileForm />
</div>
);
};
return <div>{render()}</div>;
};
const mapStateToProps = ({ auth }) => ({ auth });
export default connect(mapStateToProps)(Profile);
这是我的withLogin.js 文件:
import React from 'react';
import RequireLogin from './RequireLogin';
export default () => Component => <RequireLogin component={Component} />;
,这里是RequireLogin.js:
import React from 'react';
import { connect } from 'react-redux';
import Loading from '../Loading';
import { Redirect } from 'react-router-dom';
export const RequireLogin = ({ component: Component, ...rest }) => {
switch (rest.auth) {
case null:
return <Loading />;
case false:
return <Redirect to='/' />;
default:
return <Component />;
}
};
const mapStateToProps = ({ auth }) => ({ auth });
export default connect(mapStateToProps)(RequireLogin);
编辑:看来我没有花足够的时间研究这个测试问题。我的withLogin 函数返回一个组件,因此我需要在测试用例中对其进行浅层渲染。像这样:
import React from 'react';
import { shallow } from 'enzyme';
import withLogin from '../withLogin';
test('withLogin renders RequireLogin', () => {
const MyComponent = () => <div>myComponent</div>;
const Wrapped = withLogin(MyComponent);
const wrapper = shallow(<Wrapped />);
expect(wrapper).toMatchSnapshot();
});
此快照返回我所期望的。 不过,我仍然对有关高阶组件的最佳实践有疑问。
我确实担心这个问题现在可能有点太长了,但是如果我确实对我的 HOC 做错了什么,我可能会遇到另一个问题:我很难用 Jest 测试它们。
我的withLogin.js 文件的测试文件如下所示:
import React from 'react';
import { shallow } from 'enzyme';
import withLogin from '../withLogin';
test('withLogin renders RequireLogin', () => {
const myComponent = () => <div>Component</div>;
const wrapper = withLogin(myComponent);
expect(wrapper).toMatchSnapshot();
});
但是快照只返回这个:
// Jest Snapshot v1
exports[`withLogin renders RequireLogin 1`] = `[Function]`; //Here i would expect to see an instance of <RequireLogin />
RequireLogin.js 的测试文件如下所示:
import React from 'react';
import { shallow } from 'enzyme';
import { RequireLogin } from '../RequireLogin';
import users from '../../../fixtures/users';
test('RequireLogin renders <Loading /> if auth is null', () => {
const wrappedComponent = <div>wrappedComponent</div>;
const wrapper = shallow(<RequireLogin auth={null} component={wrappedComponent} />);
expect(wrapper).toMatchSnapshot();
});
test('RequireLogin renders <Redirect to="/profile" /> if auth is false', () => {
const wrappedComponent = <div>wrappedComponent</div>;
const wrapper = shallow(<RequireLogin auth={false} component={wrappedComponent} />);
expect(wrapper).toMatchSnapshot();
});
test('RequireLogin renders <Component /> if auth is valid', () => {
const wrappedComponent = <div>wrappedComponent</div>;
const wrapper = shallow(<RequireLogin auth={users[0]} component={wrappedComponent} />);
expect(wrapper).toMatchSnapshot();
});
但是快照会返回这个:
// Jest Snapshot v1
exports[`RequireLogin renders <Component /> if auth is valid 1`] = `<[object Object] />`; //Here i would expect <Component />
exports[`RequireLogin renders <Loading /> if auth is null 1`] = `<Loading />`;
exports[`RequireLogin renders <Redirect to="/profile" /> if auth is false 1`] = `
<Redirect
push={false}
to="/"
/>
`;
我所有其他组件的所有快照测试都按预期工作。我怀疑它可能与连接到我的 Redux 存储的RequireLogin 组件有关,但我没有在测试文件中模拟存储?提前感谢您的帮助!
【问题讨论】:
标签: reactjs unit-testing jestjs higher-order-functions higher-order-components