lundi 3 août 2020

State not set with jest mock

Component code:

constructor(props) {
        super(props);

        this.handleAuthentication = this.handleAuthentication.bind(this);

        this.state = {
            validAuthCode: true,
        }
    }

    async handleAuthentication(e) {
        e.preventDefault();
    
        try {
            let validAuthCode = await createPermanentAuth(this.state.authCode);
            if (validAuthCode) {
                this.props.history.push("/");
            }
            this.setState({ validAuthCode: false });
        } catch(e) {
            // error handling
        }
    }

    render() {
        return (
            <form onSubmit={this.handleAuthentication.bind(this)} data-testid="create-permanent-auth">
                <label htmlFor="code">Auth code:</label>
                <input id="code"
                    name="code" 
                    placeholder="12345" 
                    className={this.state.validAuthCode ? 'valid-data' : 'invalid-data'}
                    onChange={this.handleAuthCodeChange.bind(this)} />
                <input type="submit" value="Submit" />
            </form>
        );
    }

Test:

jest.mock('../yasClient');
.
. 
import { createPermanentAuth } from '../yasClient';

beforeEach(() => {
    token = screen.getByLabelText('Auth code:');
    
    expect(screen.queryByTestId('bad-code-message').classList.contains('hidden')).toBe(true);
});


it("shows authcode outlined in red and error message displayed, when bad token entered.", () => {
    createPermanentAuth.mockReturnValueOnce(false);

    fireEvent.change(token, {  target: { value: '1' } });
    fireEvent.submit(screen.getByTestId('create-permanent-auth'));

    expect(createPermanentAuth).toHaveBeenCalledTimes(1);
    expect(token.classList.contains('invalid-data')).toBe(true);
    expect(screen.getByTestId('bad-code-message').classList.contains('visible')).toBe(true);
});

Looks like validAuthCode doesn't get set to false, for whatever reason.

token.classList.contains('valid-data') returns true, and I'd expect token.classList.contains('invalid-data') to return true.

I'm wondering whether I'm missing something. I'm guessing the problem may have something to do with asynchronicity and/or how setState is being called.

Aucun commentaire:

Enregistrer un commentaire