Search code examples
typescripttestingtypesjestjsenzyme

Exact types for ReactWrapper in enzyme using typescript


I'm testing my custom components using jest with enzyme (using typescript), so I'm creating tests like:

const wrapper = mount(<MyCustomComponent/>);
expect(wrapper).toMatchSnapshot();

However, mounts return type is ReactWrapper, so I'm using it:

const wrapper: ReactWrapper = mount(<MyCustomComponent/>);
expect(wrapper).toMatchSnapshot();

And it's still ok. But digging deeper brought me to knowledge that ReactWrapper is generic. And... mount function has 3 declarations. All the time I used it like this:

const wrapper: ReactWrapper<MyCustomComponent> = mount(<MyCustomComponent/>);
expect(wrapper).toMatchSnapshot();

But now I'm afraid it's not ok. I strongly want to use exact types. What exactly should I put into diamonds operator for ReactWrapper?


Solution

  • Ok, I found the answer in documentation.

    ReactWrapper and ShallowWrapper has 3 generic arguments. Let's say we have:

    export Interface ComponentProps {
        someComponentProp: string;
    }
    
    export interface ComponentState {
        someComponentState: string;
    }
    
    export class MyCustomComponent extends React.Component<ComponentProps, ComponentState> {
    
    }
    

    In such a code, test DOM objects should have following types:

    const wrapper: ReactWrapper<MyCustomComponent, ComponentProps, ComponentState> = mount(<MyCustomComponent/>);
    expect(wrapper).toMatchSnapshot();
    

    However, there's a problem with find. In following code:

    const wrapper: ReactWrapper<MyCustomComponent, ComponentProps, ComponentState> = mount(<MyCustomComponent/>);
    const subWrapper: ReactWrapper = wrapper.find(SubComponent);
    expect(subWrapper).toMatchSnapshot();
    

    the subWrapper type cannot be: ReactWrapper<SubComponent, SubComponentProps, SubComponentState> - it won't compile. It'll force using:

    const wrapper: ReactWrapper<MyCustomComponent, ComponentProps, ComponentState> = mount(<MyCustomComponent/>);
    const subWrapper: ReactWrapper<React.Component<SubComponentProps, SubComponentState>, SubComponentProps, SubComponentState> = wrapper.find(SubComponent);
    expect(subWrapper).toMatchSnapshot();
    

    It looks awful. Fortunatelly we can get our custom type using cast via as.

    const wrapper: ReactWrapper<MyCustomComponent, ComponentProps, ComponentState> = mount(<MyCustomComponent/>);
    const subWrapper: ReactWrapper<SubComponent, SubComponentProps, SubComponentState> = wrapper.find(SubComponent) as SubComponent;
    expect(subWrapper).toMatchSnapshot();
    

    That's it.