How to test getDerivedStateFromProps with Jest and Enzyme

I have this simple code that is using the new getDerivedStateFromProps lifecycle:

static getDerivedStateFromProps(nextProps: Props, prevState: State) {
  if (nextProps.value !== prevState.value) {
    console.log('hello');
    return {
      value: nextProps.value
    };
  }

  return null;
}

And this is the test:

it('should call getDerivedStateFromProps', () => {
  const instance = shallow(mockComponent());

  instance.setProps({ value: 'test2' });

  expect(instance.state.value).toEqual('test2');
});

But I have this error but I know that is calling because of the console.log().

Expected value to equal:
  "test2"
Received:
  undefined

How do I test properly getDerivedStateFromProps?

I'm using:

react: 16.4
react-Dom: 16.4
enzyme-adapter-react-16: 1.1.1
react-test-renderer: 16.4.1

Upvotes: 5

Views: 5618

Answers (4)

Sophie Cooperman
Sophie Cooperman

Reputation: 524

In my experience you should not call directly the "getDerivedStateFromProps" function to test it. It's part of the component's lifecycle, therefore all you need to do is to:

  1. Initiate the component with a value in state.
  2. Update props with new value.
  3. check the state (since it will be updated because the "getDerivedStateFromProps" function will be automatically called.

For example:

describe('getDerivedStateFromProps', () => {
        it('new value arrived from props and state is updated', () => {
            const newValue = 'NewVal';
            const wrapper = createAndMountComponent(params); // here initiate your component wrapper
            const instance = wrapper.instance();

            wrapper.setProps({ value: newValue });  // update props

            const { value, valueFromProps } = instance.state; // check if the value in state was updated
            expect(value).toEqual(newValue);
            expect(valueFromProps).toEqual(newValue);
        });
});

This is enough to test the "getDerivedStateFromProps" function. Of course you should not forget to update the value inside the "getDerivedStateFromProps" function:

static getDerivedStateFromProps(props, state) {
    const { value } = props;
    const { valueFromProps } = state;

    if (value !== valueFromProps) {
        return {
            value,
            valueFromProps: value
        };
    }
    return null;
}

Upvotes: 5

RenJith
RenJith

Reputation: 557

To test the static getDerivedStateFromProps we can test with the below code

let wrapper = shallow(      
        <Component {...props} />      
      );
const givenProps = {...};
const givenState = {...};
const result = wrapper.instance().constructor.getDerivedStateFromProps(givenProps , givenState );
expect(result).toEqual({
  ...
})

Upvotes: 0

Pawan Gangwani
Pawan Gangwani

Reputation: 182

wrapper = shallow() wrapper.instance.getDerivedStateFromProps

Upvotes: -2

Tomasz Mularczyk
Tomasz Mularczyk

Reputation: 36179

It's a static function with no dependency. I think you can test it in isolation like every other function:

const givenProps = {...};
const givenState = {...};
const result = MyComponent.getDerivedStateFromProps(givenProps, givenState);

expect(result).toEqual({
  ...
})

I think it is a valid approach because of getDerivedStateFromProps should not contain any side-effects and be pure - which means - given the same input it will produce the same output. And because the instance of a component has no relevance here creating one would test nothing but react internals.

This would be also similar to how you would test a redux reducer.

Upvotes: 10

Related Questions