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,不适用于以前的版本

对于使用HOC
withRouter
包装的组件的类型安全测试方法,您可以从
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}/>
  );
}