1

I cannot write correct test case for button property disable. I use TestUtils from react-addons-test-utils.

I have very simple component:

const propTypes = {
    disabled: PropTypes.func.isRequired
};

class MyComponent extends Component {

    constructor(props) {
        super(props);
    }

    render() {
        return (
            <span>
                <button id="my-button" type="submit" disabled={this.props.disabled}>
                    MyButton
                </button>
            </span>
        );
    }
}

MyComponent.propTypes = propTypes;

export default MyComponent;

And I want to write test that check if button is disabled with given props or is not disabled. And the test looks like below:

describe('MyComponent', () => {
    it('should render disabled button when props.disabled is equal to true', () => {
        // given
        const props = {
            disabled: () => true
        };

        // when
        const myComponent = TestUtils.renderIntoDocument(<MyComponent {...props}/>);

        // then
        const root = ReactDOM.findDOMNode(myComponent);
        const myButton = root.querySelector('#my-button');
        expect(myButton.disabled).toEqual(true);
    });

    it('should render enebled button when props.disabled returns false', () => {
        // given
        const props = {
            disabled: () => false
        };

        // when
        const myComponent = TestUtils.renderIntoDocument(<MyComponent {...props}/>);

        // then
        const root = ReactDOM.findDOMNode(myComponent);
        const myButton = root.querySelector('#my-button');
        expect(myButton.disabled).toEqual(false);
    })
});

And this implementation of test doesn't work. First test is passed but second is failed.

But when the propTypes is set to disabled: false instead of disabled: () => false both tests are successful.

The question is why tests are successful, when function disabled is a boolean constant value equal to false and doesn't work when disabled is a function that returns false?

logs of failure test:

expect(received).toEqual(expected)

Expected value to equal:
  false
Received:
  true

  at Object.<anonymous> (__tests__/unit/components/create/MyComponent-test.js:90:37)
      at new Promise (<anonymous>)
      at <anonymous>
  at process._tickCallback (internal/process/next_tick.js:118:7)
user
  • 4,410
  • 16
  • 57
  • 83

1 Answers1

1

It looks like you are assigning the function to the property value, not the return value of the function, you could invoke by using,

const props = {
   disabled: function() {
      return false;
    }()
}

Otherwise, you need to invoke your disabled function when testing,

expect( myButton.disabled() ).toEqual(false);
Napoli
  • 1,389
  • 2
  • 15
  • 26
  • Ok, thanks. But what is a difference between `() => false` and `function() { return false; }()`? – user Mar 23 '18 at 16:52
  • using `() => false` is the equivalent of `function() { return false; }`, which is fine, but you are assigning the property `disabled` = `function`, not the value of the function. You can check this by doing a `console.log(typeof props.disabled);`.. it will yield `function`, not `boolean`. By adding `()` you invoke the function, thus forcing the immediate return value to be assigned to `disabled`. – Napoli Mar 23 '18 at 17:07