enzyme: setState does not set state
Describe the bug A clear and concise description of what the bug is.
I’ve setup versions enzyme 3.5.0 and enzyme-adapter-react-16 1.3.0.
I’ve created an enzyme test in this commit https://github.com/polkadot-js/apps/pull/265/commits/0d048c094b91762ac6a7812f5d4c5899b71b5af5 that mounts the component that passes. If I run a test with expect(wrapper.get(0)).toBe(1);
it will show me that the component includes the correct props along with provided fixtures <Signer queue={[{"id": "test", "rpc": {"isSigned": true}, "status": "test"}]} t={[Function mockT]} />
.
So far the test I’ve written that checks expect(wrapper).toHaveLength(1);
is passing successfully.
However, I want to run a test to check that the <Modal className='ui--signer-Signer' ...
(see https://github.com/polkadot-js/apps/blob/master/packages/ui-signer/src/Modal.tsx#L89) renders correctly, but it only renders when this.state.currentItem
and this.state.currentItem.rpc.isSigned
(see https://github.com/polkadot-js/apps/blob/master/packages/ui-signer/src/Modal.tsx#L83) are defined and true. So in the commit I created fixtures for the the currentItem
state value, and wrote the following test to set the state with setState
, update the component, and then check that the state has changed. But it doesn’t appear to work, because the test results report that currentItem
is still undefined
instead of being the value I set to the fixtureCurrentItemState
variable.
it('sets the state of the component', () => {
wrapper.setState({ currentItem: fixtureCurrentItemState });
wrapper = wrapper.update(); // immutable usage
expect(wrapper.state('currentItem')).toEqual(fixtureCurrentItemState);
console.log(wrapper.debug());
});
Note that I tried debugging with console.log(wrapper.debug());
and console.log(wrapper.html());
, which I’ve used in the past without any issues, but neither of them output anything, so as an alternative I was able to check the state by running expect(wrapper.state()).toEqual(1);
, which returned {"currentItem": undefined, "password": "", "unlockError": null}
To Reproduce Steps to reproduce the behavior:
- Go to https://github.com/polkadot-js/apps
- Clone Pull Request https://github.com/polkadot-js/apps/pull/265
- Install dependencies and run the tests with
yarn; yarn run build; yarn run test;
- Remove
.skip
from the above mentioned tests - See the failing test
Expected behavior
I expected setState
to set the state
Screenshots
Code used screenshot:
Failing test screenshot:
Desktop (please complete the following information):
- OS: macOS
- Browser: Chrome
- Version 68.0.3440.106
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 1
- Comments: 26 (8 by maintainers)
Commits related to this issue
- test: Update tests but skipping since awaiting resolution of enzyme issue Reference: https://github.com/airbnb/enzyme/issues/1794 — committed to polkadot-js/apps by ltfschoen 6 years ago
- feat: Fixes Issue #260. Allow use Enter to submit extrinsics (#265) * WIP: Fixes #260. Autofocus password input field. Press tab after enter password to switch focus to submit * feat: Clicks Submi... — committed to polkadot-js/apps by ltfschoen 6 years ago
- feat: Fixes Issue #260. Allow use Enter to submit extrinsics (#265) * WIP: Fixes #260. Autofocus password input field. Press tab after enter password to switch focus to submit * feat: Clicks Submi... — committed to cennznet/cennznet-ui by ltfschoen 6 years ago
- feat: Fixes Issue #260. Allow use Enter to submit extrinsics (#265) * WIP: Fixes #260. Autofocus password input field. Press tab after enter password to switch focus to submit * feat: Clicks Submi... — committed to cennznet/cennznet-ui by ltfschoen 6 years ago
- feat: Fixes Issue #260. Allow use Enter to submit extrinsics (#265) * WIP: Fixes #260. Autofocus password input field. Press tab after enter password to switch focus to submit * feat: Clicks Submi... — committed to cennznet/cennznet-ui by ltfschoen 6 years ago
Yeah I seem to be running into this same issue. I have an instance method that sets state, so I run the instance method and ensure the the correct state gets set:
Enzyme 3.5.0 enzyme-adapter-react-16 1.3.1
I changed it to manually call
setState
on the wrapper, but the state still isn’t set.This still doesn’t set the state correctly. I even tried it with the callback on
setState
and still no-go.EDIT: Also, I’m on React 16.4.2
fwiw,
wrapper = wrapper.update();
isn’t required; “immutable” just means you have to re-find from the root.setState is async; what happens if you do:
@ltfschoen again,
await
is useless on setState and setProps, since neither returns a promise.@ljharb I tried again and it doesn’t work with the following versions. I tried using Callbacks, Promises, and Async Await, but cannot change the state using the below code.
you can setState like this
will pass
see my gist
https://gist.github.com/elvisgiv/e9056bde1cfbf5bcfecdfb32c10577ea
@ltfschoen don’t use try/catch on your code there, return a
new Promise
instead, that resolves on the callback:@comfroels thanks!
This works for me
Yes, I do believe I have a bad pattern that I’m using, as upgrading to React 16.5 causes me a very similar issue. You can close this, thanks for all the help ladies/gents!
@jgzuke Yes, I’ve established why it wasn’t setting state. I’ve changed my code to use callbacks with the following, but I’d like to refactor it to use promises instead.
I’m now trying to use
mount
instead ofshallow
, so I’ve mocked i18n with the following to overcome errorTypeError: Cannot read property 'options' of undefined
But now it’s giving error
TypeError: Cannot read property 'Symbol(Symbol.iterator)' of undefined
Thanks for that link, it’s awesome!
Sorry, haven’t responded to this yet, the component in question for me, doesn’t use
getDerivedStateFromProps
at all. I’ll be probably playing around more with this today. So I’ll check enzyme 3.4 and see if I have the same issue. I was going to try to get us up to React 16.5 todayReact calls
getDerivedStateFromProps
when a component receives either new props or state. In the original example,Signer
has agetDerivedStateFromProps
that assignsstate.currentItem
from a prop value.