Ad

How To Unit Test Forms With Sinon And Chai

- 1 answer

I am using Chai, Sinon, and Mocha to test.

I am using Redux-Forms, along with ReactJS.

I want to test what happens after I click submit on a Forgot Password page.

Here's my code so far:

react file:

propTypes: {
    fields: React.PropTypes.object.isRequired,
    message: React.PropTypes.string.isRequired,
    handleSubmit: React.PropTypes.func.isRequired,


},

renderForm: function() {
    const { fields: {email}, handleSubmit, isFetching } = this.props;
    const iconClass = "fa fa-star-o";

    return(
      <form form="forgotPassword" name="forgotPassword" className="stack-input">
          <ReduxFormTextInput
              {...email}
              floatingLabelText="Email Address" />

          <div className="clearfix" />

          <div className="form-footer">
              <ButtonSpinner spinner={isFetching} onClick={handleSubmit} ripple={true} raised={true} primary={true} >
                  <i className={iconClass} />Send
              </ButtonSpinner>
          </div>
      </form>
    );

},

renderMessage: function() {
    return(
        <div>
            <i className="fa fa-exclamation-circle" style={{marginRight: '4px'}}/>
            If your email is in the system, then it will be sent.
        </div>
    );

},

//Checks if user has submitted email.
emailSubmit: function(){
    var locus = this, props = locus.props;
    if(props.message === ''){
        return null;
    }
    else if(props.message === 'SENT'){
        return true;
    }
    return null;
},


render(){

    var locus = this, props= locus.props;


    return(
          <div className="page-wrap">
            <div className="page-column">
                <h2>Forgot Your Password</h2>
                {this.emailSubmit() ? this.renderMessage(): this.renderForm()}

            </div>
          </div>
        );
}

unittest file:

describe('ForgotPasswordForm', () => {
    const component = setup({
            fields: {
                email: {

                    onChange: spy(),
                    onBlur: spy(),
                    onFocus: spy()
                }
            }, // React.PropTypes.object.isRequired,
            message: '', // React.PropTypes.string.isRequired,
            handleSubmit: spy() // React.PropTypes.func.isRequired,
            //onClearMessage:spy() //,  React.PropTypes.func.isRequired
        }),
        domRoot = TestUtils.findRenderedDOMComponentWithClass(component, 'page-wrap'),
        title = TestUtils.findRenderedDOMComponentWithTag(component, 'h2'),
        submitButton = TestUtils.findRenderedDOMComponentWithClass(component, 'material-D-button'),
        form = TestUtils.findRenderedDOMComponentWithTag(component, 'form'),
        inputs = TestUtils.scryRenderedDOMComponentsWithTag(component, 'input'),
        emailInput = inputs[0];

This test keeps failing, despite multiple attempts. I am not experienced with Spy(), so I'm not sure if I am suppose to be using calledWith.

it ('should display "If your email is in the system, then it will be sent." on submit', () => {

        TestUtils.Simulate.change(emailInput, {target: {value: '[email protected]'}});
        TestUtils.Simulate.click(submitButton);
        expect(domColumn.text).to.equal("Forgot Your Password");
    });

This is the response I get.

+"If your email is in the system, then it will be sent."
-  -"Forgot Your PasswordSend"

I used innerHTML to get a sense of what's being populated after the click, and I don't think the click is even registering.

When I try to do TestUtils.Simulate.change(emailInput, {target: {value: '[email protected]'}});, it doesn't work. I have to populate the value of the email in the component.

Ad

Answer

You should be assigning your handleSubmit spy to a constant so you can at least be able to check whether it's getting called. (Probably the same for the other spies).

const handleSubmitSpy = spy()
const component = setup({
        ...
        handleSubmit: handleSubmitSpy

Now you can check expect(handleSubmitSpy).toHaveBeenCalled().

Ad
source: stackoverflow.com
Ad