Reactjs 如何使用RouteComponentProps测试React组件?
我有一个组件,它具有扩展Reactjs 如何使用RouteComponentProps测试React组件?,reactjs,typescript,testing,react-router,jestjs,Reactjs,Typescript,Testing,React Router,Jestjs,我有一个组件,它具有扩展RouteComponentProps的道具,如下所示: export interface RouteComponentProps<P> { match: match<P>; location: H.Location; history: H.History; staticContext?: any; } 导出接口RouteComponentProps{ 匹配:匹配; 地点:H.地点; 历史:H.历史; 静态上下文?:任何; }
RouteComponentProps
的道具,如下所示:
export interface RouteComponentProps<P> {
match: match<P>;
location: H.Location;
history: H.History;
staticContext?: any;
}
导出接口RouteComponentProps{
匹配:匹配
;
地点:H.地点;
历史:H.历史;
静态上下文?:任何;
}
现在,当我在应用程序中使用我的组件时,我会将这些道具传递给它:
<MyComponent
match={this.props.match}
location={this.props.location}
history={this.props.history}
/>
道具已经可用,因为它在react路由器内运行
现在,如何在没有匹配
,位置
,历史记录
可用的情况下测试此组件
我需要模拟它们吗?或者它应该以某种方式自动加载一些辅助函数吗?我一直在寻找一个很好的解决方案。我希望我可以在mapStateToProps函数或类似的东西中实现它,但目前还不能做到这一点 我能做的最好的事情就是模仿这个,在比赛、地点和历史中传球。我使用了以下方法:
import { RouteComponentProps } from 'react-router'
import { match } from 'react-router-dom';
import {UnregisterCallback, Href} from 'history'
export function getMockRouterProps<P>(data: P) {
var location: {
hash: "",
key: "",
pathname: "",
search: "",
state: {}
};
var props: RouteComponentProps<P> = {
match: {
isExact: true,
params: data,
path: "",
url: ""
},
location: location,
history: {
length:2,
action:"POP",
location: location,
push: () => {},
replace: () => {},
go: (num) => {},
goBack: () => {},
goForward: () => {},
block: (t) => {
var temp: UnregisterCallback = null;
return temp;
},
createHref: (t) => {
var temp: Href = "";
return temp;
},
listen: (t) => {
var temp: UnregisterCallback = null;
return temp;
}
},
staticContext: {
}
};
return props;
}
从“react router”导入{RouteComponentProps}
从'react router dom'导入{match};
从“历史记录”导入{UnregisterCallback,Href}
导出函数getMockRouterProps(数据:P){
风险值位置:{
散列:“”,
关键字:“,
路径名:“”,
搜索:“,
国家:{}
};
var props:RouteComponentProps
={
匹配:{
是的,
参数:数据,
路径:“”,
网址:“
},
地点:地点,,
历史:{
长度:2,
行动:“流行”,
地点:地点,,
推送:()=>{},
替换:()=>{},
go:(num)=>{},
goBack:()=>{},
goForward:()=>{},
块:(t)=>{
var temp:UnregisterCallback=null;
返回温度;
},
createHref:(t)=>{
var-temp:Href=“”;
返回温度;
},
听:(t)=>{
var temp:UnregisterCallback=null;
返回温度;
}
},
静态上下文:{
}
};
返回道具;
}
然后在我的测试中,我做到了:
var routerProps = getMockRouterProps<ReduxTestComponentProps>(null);
const wrapper = mount<ReduxTestComponent, ReduxTestComponentState>(
<ReduxTestComponent
history={routerProps.history}
location={routerProps.location}
match={routerProps.match}
isLoadingTodo={false}
todos={todos}
addAsyncTodoActionDispatch={() => mockTodoAddDispatch()}
deleteTodoActionDispatch={() => mockTodoDeleteDispatch()}
/>
);
var-routerProps=getMockRouterProps(null);
常量包装器=装入(
mockToLoadDispatch()}
deleteTodoActionDispatch={()=>mockTodoDeleteDispatch()}
/>
);
要回答您的最后一个问题,建议您在测试中使用<*您的组件*>
。Typescript没有发现该组件将向您的组件传递所需的道具,因此我假设它不是一种类型安全的方法
这适用于React Router v4,不适用于以前的版本
对于使用HOCwithRouter
包装的组件的类型安全测试方法,您可以从react router
和history
包中构建位置、历史记录和匹配
本例使用酶和快照测试,但也可以很容易地用于任何其他测试
这避免了我需要使用
作为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();
});
一位名叫Timmy Huang的先生提供了一个解决方案,其中包括一个简单的模拟 我试着开玩笑,结果成功了。我的组件有这个签名
export const MyComponent: React.FC<RouteComponentProps> = ({location}:RouteComponentProps) => {
export const MyComponent:React.FC=({location}:RouteComponentProps)=>{
我的基本测试,以确认组件负载,然后看起来像这样
function renderMyComponent() {
return render(
<MyComponent {...routeComponentPropsMock}/>
);
}
函数renderMyComponent(){
返回渲染(
);
}
v5的history
不再具有createLocation
。
const routeComponentPropsMock = {
history: {} as any,
location: {} as any,
match: {} as any,
}
export const MyComponent: React.FC<RouteComponentProps> = ({location}:RouteComponentProps) => {
function renderMyComponent() {
return render(
<MyComponent {...routeComponentPropsMock}/>
);
}