我有一个组件,它具有扩展 RouteComponentProps
的 Prop ,如下所示:
export interface RouteComponentProps<P> {
match: match<P>;
location: H.Location;
history: H.History;
staticContext?: any;
}
现在,当我在应用程序中使用我的组件时,我将这些 Prop 传递给它:
<MyComponent
match={this.props.match}
location={this.props.location}
history={this.props.history}
/>
Prop 已经可用,因为它在 React 路由器中运行。
现在,如何在没有可用的match
、location
、history
的情况下测试这个组件?
我需要模拟它们还是应该以某种辅助函数自动加载它们?
最佳答案
要回答您的最后一个问题,推荐的方法是使用 <MemoryRouter>< *your component here* ></MemoryRouter>
在你的测试中。 Typescript 没有意识到该组件会将所需的 Prop 传递给您的组件,因此我认为它不是是一种类型安全的方法。
这适用于 React Router v4,不适用于以前的版本。
用于测试用 HOC 包装的组件的类型安全方法 withRouter
您可以从 react-router
构建位置、历史记录和匹配项和 history
包。
此示例使用 enzyme 和快照测试,但可以很容易地成为任何其他测试。
这避免了我需要使用 <MemoryRouter>
作为 typescript 无论如何都不喜欢的包装器。
// Other imports here
import { createMemoryHistory, createLocation } from 'history';
import { match } from 'react-router';
const history = createMemoryHistory();
const path = `/route/:id`;
const match: match<{ id: string }> = {
isExact: false,
path,
url: path.replace(':id', '1'),
params: { id: "1" }
};
const location = createLocation(match.url);
test('shallow render', () => {
const wrapper = shallow(
<MyComponent history={history}
location={location}
match={match} />
);
expect(wrapper).toMatchSnapshot();
});
注意不要使用它来测试实现细节,它可能很诱人,但如果您想重构,它会给您带来很多痛苦。
为此制作一个助手可能是使其可重用的最佳方式。
import { createLocation, createMemoryHistory } from 'history';
import { match as routerMatch } from 'react-router';
type MatchParameter<Params> = { [K in keyof Params]?: string };
export const routerTestProps = <Params extends MatchParameter<Params> = {}>
(path: string, params: Params, extendMatch: Partial<routerMatch<any>> = {}) => {
const match: routerMatch<Params> = Object.assign({}, {
isExact: false,
path,
url: generateUrl(path, params),
params
}, extendMatch);
const history = createMemoryHistory();
const location = createLocation(match.url);
return { history, location, match };
};
const generateUrl = <Params extends MatchParameter<Params>>
(path: string, params: Params): string => {
let tempPath = path;
for (const param in params) {
if (params.hasOwnProperty(param)) {
const value = params[param];
tempPath = tempPath.replace(
`:${param}`, value as NonNullable<typeof value>
);
}
}
return tempPath;
};
现在我们可以使用 routerTestProps
在我们的测试中发挥作用
const { history, location, match } = routerTestProps('/route/:id', { id: '1' });
关于reactjs - 如何使用 RouteComponentProps 测试 React 组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46927392/