How To Unit Test React Component With react-intl, react-router-dom v4 and TypeScript

跟風遠走 提交于 2021-02-07 10:28:14

问题


I'm currently trying to unit test a function in a React Class Component. I've tried everything that I can come across to get access to the actual Component.

The application is currently setup as follows:

<IntlProvider ...>
    <BrowserRouter>
        <App/>
    </BrowserRouter>
</IntlProvider>

The Component I'd like to test, lets call it Users, is defined inside of as:

<Route
    path="/users"
    render={(routeProps) => {
        return (
            <Users
                {...routeProps}
            />
        );
    }}
/>

The users component is as such:

type Props = {...}

type State = {...}

class Users extends Component<Props, State> {

    constructor(props: any) { super(props); }

    componentDidMount() { ... }

    componentWillUnmount() { ... }

    isReadOnly = (): boolean => {
        // determine if read only.
    }

}

export default withRouter(Users)

and I'm trying to test a function called isReadOnly. I need to perform setState() on the component before I can actually call the function however.

So far I've tried:

const wrapper = shallow(<OrderEntry {...props}/>);

But it throws an error: ShallowWrapper::setState() can only be called on class components

I figured this had to be because of the BrowserRouter. So I find that I need to wrap in MemoryRouter to get around this.

const wrapper = shallow(<MemoryRouter><Users {...props}/></MemoryRouter>);
const usersInstance = wrapper.find(Users).dive().instance();
usersInstance.setState(state);

This throws the error: TypeError: Cannot read property 'setState' of null

If I console.log(wrapper), it outputs: ShallowWrapper {}.

I'm a bit lost on this one...I just need to be able to do 2 things - Set State, and Unit Test one of the Components Function.


回答1:


Redux docs suggest to export the unconnected component (Users in your case) and use it in the tests. That way, you have complete control over the props passed to the rendered instance and, as a bonus, no issues with using enzyme's setState.

So something like:

export class Users extends Component<Props, State> {

    componentDidMount() { ... }

    componentWillUnmount() { ... }

    isReadOnly = (): boolean => {
        // determine if read only.
    }
}
export default withRouter(Users);

And in tests:

import {Users} from "./Users";


来源:https://stackoverflow.com/questions/59920008/how-to-unit-test-react-component-with-react-intl-react-router-dom-v4-and-typesc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!