Comments (30)
@bricejlin
#318 is hidden in the lifecycleExperimental
flag.
You can do with the flag for enabling all lifecycle methods in shallow
.
shallow(<Foo />, { lifecycleExperimental: true })
from enzyme.
At the moment I'm doing
const prevProp = wrapper.props()
wrapper.setProps({
current_step: 2,
})
// forces an update call to componentDidUpdate - https://github.com/airbnb/enzyme/issues/34
wrapper.instance().componentDidUpdate(prevProp)
from enzyme.
The latest update seems to broke this again.
node_modules/enzyme/build/ShallowWrapper.js
line 552
if (lifecycles.componentDidUpdate && typeof instance.componentDidUpdate === 'function' && (!state || (0, _Utils.shallowEqual)(state, _this3.instance().state))) {
instance.componentDidUpdate(prevProps, state, snapshot);
}
The last condition make it that only state change will trigger instance.componentUpdate,
from enzyme.
In react-native lifecycleExperimental
works for componentDidMount()
but not for componentDidUpdate()
.
"name": "enzyme",
"version": "3.1.0",
"react": "16.0.0",
"react-native": "0.47.2",
from enzyme.
Sorry to bring an old thread back up, but I'm running into a similar issue detailed here, and I can't seem to find any other solutions when searching. Here's my test:
it('should reset gridWrapperNode scrollTop position if data has changed', () => {
const mounted = mount(<Grid {...props} />);
const gridNode = document.createElement('div');
const gridWrapper = document.createElement('div');
gridWrapper.classList.add('datagrid-grid-wrapper');
gridNode.appendChild(gridWrapper);
mounted.instance().gridNode = gridNode;
gridWrapper.scrollTop = 40;
mounted.instance().lastScrollTop = 40;
mounted.setProps({
...props,
data: [{ val: 'someNewData' }],
});
// mounted.instance().componentDidUpdate({});
expect(gridWrapper.scrollTop).toEqual(0);
expect(mounted.instance().lastScrollTop).toEqual(0);
});
When I uncomment out // mounted.instance().componentDidUpdate({});
, it works as expected, however I'm expecting the componentDidUpdate
method to be called with the props changing. I checked, the props are updating as they should so I was wondering if this is a known issue or if it's something I'm doing wrong?
from enzyme.
FWIW, setProps
is being deprecated.
https://github.com/facebook/react/pull/5588/files
http://facebook.github.io/react/blog/2015/10/07/react-v0.14.html#new-deprecations-introduced-with-a-warning
from enzyme.
@blainekasten thanks for that info. Funny - I didn't even know .setProps()
existed as a real API.
The deprecation doesn't affect us in this case, since .setProps()
is achieved using setState()
of a parent wrapper component, anyway.
from enzyme.
Solved it by using
wrapper.setProps({
user: {
test: {error: "test"}
}
});
wrapper.find('.smth').simulate('click');
Works as a charm, setprops are set, you just need to call a function again that triggers the component o re-render, it will trigger the componentDidUpdate function
from enzyme.
+1, how correctly to solve the problem?)
from enzyme.
I'm betting this will be resolved by #318
from enzyme.
I'm also performing similar hacks to what @CurtisHumphrey mentioned above.
I wonder what the preferred way of achieving this is, if not with setProps
? I have yet to dig in too deep myself, but this is something I am definitely interested in contributing to. It looks like #318 is on a good track.
from enzyme.
#318 is now merged. Do we know if this is still a problem? Can any of the affected devs here confirm?
from enzyme.
hi @blainekasten I'm using the latest release 2.4.1 and it still hasn't fixed the issue. I ended up having to use mount
to trigger the componentDidUpdate
. Would love to just use shallow
instead
from enzyme.
Closing since this should be resolved by using lifecycleExperimental
flag.
from enzyme.
FWIW, I think @CurtisHumphrey 's approach is closest to the best approach. Why do people find it necessary to test if React fires a lifecycle event? If React fails to go through lifecycle events, then React has a larger issue. Testing if react fires a lifecycle event when a prop updates is pointless. The whole point of React is to "react" to prop and state changes. It's like testing to make sure image.onload, or window.onload fires in a browser. If these built-in browser events fail to fire in Chrome when they are supposed to fire, then Google is out of business the next day.
I think in general, people over-test things that don't need to be tested. I also think that people forget that your React components are 90% vanilla javascript.
You don't always need enzyme. React is just javascript. If your ES6 class constructor looks like this...
constructor(props) {
super(props);
// other stuff here...
}
Then you can test if componentDidUpdate works correctly, without having to test if React fires it when it's supposed to fire it.
describe('componentDidUpdate()', () => {
it('should do something', () => {
const prevProps = { // define previous props };
const prevState = { // define previous state if needed };
const instance = new MyComponent({ // new props go here });
instance.state = { // if you need a new set state, set it here };
// some method called by componetDidUpdate when there is an update.
instance.someMethod = jest.fn();
instance.componentDidUpate(prevProps, prevState);
// expect stuff here.
expect(instance.someMethod).toHaveBeenCalledWith( stuff );
})
})
This is what is called "unit testing" a class method. Enzyme shallow() is not a unit test. It is an integration test. Enzyme shallow() mounts a shallow version of a component in a virtual browser.
A true unit test only focuses on a function or method.
The test above tests the inputs of the componentDidUpdate() class method, tests the expected side effects of the class method, and does all of this without redundantly testing if React works.
I like Enzyme, but it is not always the answer.
from enzyme.
@mrbinky3000 First, you should be using testing a component the way it's used - new MyComponent
is never how it's used in production, so that test is not very valuable.
As for "integration test", everything should be an integration test - if it's not one, then your test has to have knowledge about the implementation under test, which is coupling, and makes your tests more brittle.
Enzyme certainly isn't always the answer, but setting up a contrived scenario to test something in an environment in which it never runs in production gives you nothing but false confidence.
from enzyme.
Sorry if this was off-topic. I can discuss this further offline if you want. I've been thinking about this for a while now and would like to know more about why you think this is bad. But here are some things to consider.
- All tests are contrived.
- If you properly unit test all the class methods and/or functions for a given Component, then the sum of your units should be ok. Garbage in garbage out, and vice versa.
- You still need integration tests like shallow and mount. For example, I still use them to test any conditional statements in a render() method. My argument is people need a fraction of the shallow and mount tests that they create today.
from enzyme.
The sum of your unit tests is not equal to integration tests. You might be able to “get by” with more focused unit tests and fewer wrappers, but those aren’t better tests - those are more contrived since, unlike the wrappers, they don’t mimic production usage.
from enzyme.
@LiangMingChen could you file a new issue about this, and fill in the entire issue template? That would really help it get fixed quickly.
from enzyme.
@ljharb @LiangMingChen I'm encountering that as well, was the issue created ?
from enzyme.
Nope, please file one :-)
from enzyme.
Nope, please file one :-)
Turns out it works sorry
from enzyme.
@Jmac1523 try adding mounted.update()
.
from enzyme.
@ljharb I tried, unfortunately to no avail. Is the test less-effective or even ineffective with mounted.instance().componentDidUpdate({});
?
from enzyme.
@Jmac1523 can you file a new issue?
from enzyme.
sure, thanks for getting back to me!
from enzyme.
@Jmac1523 that instance call will only work on state based components. I suppose lifecycle methods only exist in those but then there is the challenge of testing the useEffect method (on update, render, etc.). IMHO there needs to be some support for this from the Enzyme team. shallow doesn't buy you much as Enzyme shallow isn't going to be tied into your lifecycle methods.
from enzyme.
Err...I know, I never said I was using Hooks
from enzyme.
@Jmac1523 I realize that but with so many components being developed with hooks and moving away from state based it's worth noting. If you find any leads on this let me know. I'm doing some research on a state based approach now. This is something that needs attention from the Enzyme team.
from enzyme.
@Jmac1523 and everyone else. This solution seems to work nicely for testing state-based component lifecycle methods:
it('should call componentDidUpdate', () => {
let node = document.createElement('div');
let instance = ReactDOM.render(table, node);
const spy = jest.spyOn(Table.prototype, 'componentDidUpdate');
ReactDOM.render(modifiedTable, node);
expect(spy).toHaveBeenCalled();
})
This is hitting that component during runtime:
Ultimately what I'm doing here is setting the table (JSX) on the DOM then just loading in a table with modified properties. Here's the table in Jest:
const justTheTable = (
<Table
data={fossilsMainDirectory}
defaultSortType="string"
defaultSortKey="class"
defaultSortAsc={true}
columnConfiguration={columns.desktop}
tabletOverrideColumnConfiguration={columns.tablet}
mobileOverrideColumnConfiguration={columns.mobile}
>
{({ filter }) => {
return (
<>
<h1>Hello Spec</h1>
</>
);
}}
</Table>
);
const table = (
<ThemeProvider theme={theme}>
{justTheTable}
</ThemeProvider>
);
from enzyme.
Related Issues (20)
- enzyme-adapter-react-18 HOT 2
- Component is not re-rendered with updated states HOT 5
- Cheerio 1.0.0-rc.11 no longer support deep imports HOT 3
- enzyme crash since Cheerio 1.0.0-rc.11 release HOT 5
- CSS selectors match component props rather than rendered DOM HOT 6
- Cannot read property 'child' of undefined on React 16 + enzyme-adapter-react-16 HOT 1
- Cannot read property 'child' of undefined enzyme-adapter-react-16 and react 17.0.2 HOT 3
- "TypeError: Cannot read properties of undefined (reading 'current')" in mount API HOT 7
- Method “props” is only meant to be run on a single node. 0 found instead. HOT 1
- How to test the form which is rendered based on props in class component in react.js ? HOT 3
- How to test the state values which are setting the state from local storage inside componentDidMount in enzyme using reactjs ? HOT 5
- Function `mount` does not mock proper data HOT 5
- [email protected] does not include latest changes as per master HOT 5
- Document `getElement(s)` for full DOM rendering HOT 3
- TypeError: window.require is not a function HOT 5
- Does Enzyme support React 18.0.2 ? HOT 1
- Is this library 'dead'? HOT 5
- Explain how the synchronization works HOT 1
- Mount and simulate are failing after changing to Node 16 HOT 10
- enzyme-adapter-react-18 HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from enzyme.