mercredi 19 septembre 2018

Unexpected behaviour testing React component after delay with Jest/Enzyme

I have a pretty basic React component that displays a sequence of dots for when something is loading, by default it displays up to 3 dots and the dots increment on an interval set within a componentDidMount function, resetting at the number of dots. The number of dots and interval can both be overwritten by passing through props. This component is below.

import * as React from 'react';

export interface Props {
    interval?: number;
    dots?: number;
}

class LoadingDots extends React.Component<Props, object> {
    public static defaultProps: Partial<Props> = {
        interval: 300,
        dots: 3
    };
    interval: any;

    state = {
        frame: 1,
        interval: this.props.interval,
        dots: this.props.dots
    }

    componentDidMount = () => {
        this.interval = setInterval(() => {
            this.setState({
                frame: this.state.frame + 1
            });
        }, this.props.interval);
    }

    componentWillUnmount() {
        clearInterval(this.interval);
    }

    public render() {
        let dots = this.state.frame % (this.props.dots + 1);
        let text = "";
        while (dots > 0) {
            text += ".";
            dots--;
        }
        return (
                <p className="loadingDots" {...this.props}>{text}</p>
        )
    }
}

export default LoadingDots;

The issue I'm now having is testing this component, following the Jest Documentation and Jest react testing: Check state after delay I have written the test below to check the correct default number of dots are rendered at the end of the set of frames (would pass with a 200ms delay).

test('LoadingDots by default renders with 3 dots', () => {
    var loadingDots = Enzyme.shallow(<LoadingDots interval={100} />);
    jest.useFakeTimers();
    jest.runAllTimers();
    setTimeout(() => {
        expect(loadingDots.find('p').text()).toBe("...")
    }, 300);
});

This test passes but shouldn't, it passes regardless of what value I put in the .ToBe of expect(loadingDots.find('p').text()).toBe("...").

I've tried rendering the component as var loadingDots = Enzyme.mount(); and var loadingDots = Enzyme.render(); but still the same outcome, does anyone see what's going wrong here? How can I get this to work correctly?

Aucun commentaire:

Enregistrer un commentaire