enzymejs / enzyme

JavaScript Testing utilities for React

Home Page:https://enzymejs.github.io/enzyme/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

React hooks support checklist

chenesan opened this issue · comments

Sorry for removing issue template. Since the React 16.8 is out we can start to work on hooks support in enzyme now. Previously I tried to open PR in #2008 to help with this but found out that there are too many apis in React hooks. After some thinking I feel it's better to track all of the supports / PR in one issues, and create one PR for each hooks api (useState, useEffect, etc).

known issues (some are resolved with newer version of react):

  • setState returned from useState not works with shallow before react@16.8.5 . Fixed in facebook/react#15120 .
  • useEffect and useLayoutEffect not works with shallow because react shallow renderer doesn't run it. (facebook/react#15275)
  • useCallback doesn't memoize callback in react shallow renderer (facebook/react#15774)

Currently I'm working in useState (#2008) and I'm glad to see if anyone else would like to help to support other apis. For now we need to add many tests to make sure what is working in enzyme, and what is not, then add patch / feature into it. I can help to maintain the above checklist if there are any related issues / PR .

I'm simply volunteer to do this and not a main maintainer here though so @ljharb if you have had any plan / schedule on this feel free to tell me and I can change or close this :-)

commented

Thanks for making this list @chenesan!
@ljharb, I'm interested in tackling some of this features too. It might take me some time to finish implementing it as I'm getting a little busy in the next two weeks, but I am very interested in helping out.
I've currently worked on two test cases #2029

If no one has took up the useEffect feature. I would like to try that out!

Hi @k3ithl1m glad to see your work :) FYI I just open #2034 to wrap render function of mount renderer with act(). That should be related to useEffect test cases and I hope that help!

@chenesan Also note that React seemed to have an issue with shallow rendering hooks right now. Not sure if it was addressed by the React time already or not.

@AnaRobynn Didn't they solve this with facebook/react#14567 ?

@nixstrom It’s supported, but there are issues apparantly. I saw Dan tweeting about it yesterday: https://twitter.com/dan_abramov/status/1103304963445403648?s=21

I think the issue should be facebook/#14841, which #2008 would depends on.

@chenesan @k3ithl1m : Added test cases #2041 for useEffect, useState & custom hooks along with combination of those. Will add few more soon. I was thinking to get some support as a focus (micro) team for react hooks test cases considering all scnerios.

@chenesan : Please add #2041 in custom hooks checklist item as I added test case in that PR

@ljharb @chenesan : Simple hooks testing is successful in mount rendering without act :)
Example: https://codesandbox.io/s/5xkjk1ql14

@pgangwani I believe the test could pass without act. However when it comes to setting state in useEffect without act wrapping and assert the state changes after mount (like test case of #2034 ), it would fail. Since #2034 is merged this should be fine to mount render without act(), though.

I'm not sure if that would pass without act wrap. but since we wrap mount with act in master now, this should be fine I think.

@chenesan : [Update]: Added test cases for useReducer & useContext. Few custom hooks too

Are there any updates on when useMemo will be supported with shallow rendering?

Specifically I'm rendering a connected react-redux component. Since react-redux is now relying on hooks, I'm getting the "Invalid hook call" when it attempts to call useMemo.

I can workaround using mount for now, but would prefer to keep all of my tests using shallow.

@tlginn in the next release of enzyme, hopefully.

Running enzyme tests using render method keeps spamming my ci test log with Warning: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server renderer's output format. has anyone came across it or found a way to make these not appear?

Hi @VicJer I might try to write some tests around useLayoutEffect to see if we could reproduce the warning :-)

@VicJer I found out the warning is because enzyme uses ReactDOMServer.renderToStaticMarkup to stringify the rendered output in enzyme's render(). So when we call useLayoutEffect with the ssr method the warning will alert. Seems the only way to suppress the warning is not to use useLayoutEffect when using render() in test environment. Sorry that I couldn't figure out a better way to handle this :-\

Sorry if this isn't helpful but I just want to double check - are other's still unable to shallow render any components with hooks in them or have I just missed something in the various bug reports/questions/responses? Are we still waiting on #2011 (comment) ? I haven't been able to get it working but it might be something on my side.

@bencoullie shallow renderer doesn't work with useEffect now. See facebook/react#15275 . If you have any other issue around shallow renderer please open a new issue and we can know / fix it.

v3.10.0 has now been released.

Are there any changelog or docs? @ljharb

Yes, here. But seems nothing hooks related.

Most of the hook-related things are in the react 16 adapter.

Most of the hook-related things are in the react 16 adapter.

Which doesn't seem to have a changelog at all =( https://github.com/airbnb/enzyme/tree/master/packages/enzyme-adapter-react-16

I have had a little play and I’ve been able to remove act() in certain situations in tests with components using hooks. But I still need to use it when using useState

Is the checklist at the top updated, @chenesan ? I'm confused by some of the comments that follow. I can't tell if hooks are supported in Enzyme yet.

@Hypnosphi the changelog for the adapters is in the version bump commit itself: dc724f0

i will admit that i've had a hard time understanding what changes are included in which package as well.

i've found that to be true in almost all monorepos, though, so its not in any way limited to this one (part of the reason i think monorepos favor maintainers over consumers, which is probably the appropriate balance in many ways).

i usually look for a github release first, then try the changelog, but often forget to check the commit (or lose motivation by that point).

I hate monorepos, but it's what makes the most sense for this project.

I would be more than happy to (in a separate issue or PR) discuss suggested alternatives for changelog management that makes things more discoverable and consistent.

@tarikhamilton I tried updating related issues and test case pr after a perod of time. The known issues are recorded in the issue body. Maybe there are still some use cases we didn't cover(but we don't know), if you find any issue please feel free to open an issue or comment so we can support hooks more properly.

@chenesan it'd be helpful if you could check off the boxes in the OP that are completed.

@ljharb I just check off the item whose test cases are merged; Most of the items are stuck at #2041 .

Thanks for the PRs and work here. What is the best way to know when we can use hooks like useEffect in our components that are tested by Enzyme's shallow render etc? Is it to check in on this issue and it's checklist periodically? Will it be in a discoverable changelog? Or should I watch facebook/react#15275?

@bencoullie You could watch facebook/react#15275 and facebook/react#15589. Not sure if it is possible to fix this with only works in enzyme side .

I've merged all the outstanding hooks-related PRs.

Let's put up the PRs needed to close this issue:

  1. document in the readme, known limitations with hooks, and link back to all the filed react/shallow renderer bugs
  2. put up test cases for any missing hook coverage
  3. file followup issues to investigate any skipped test cases that aren't blocked on an upstream FB change.

Thanks!

@ljharb Filed an issue for (3) in #2165 . I think there's no other .shallow issue in enzyme side now. Also open #2164 for (1). After these works finished I think we can close this issue :-)

Any news on releasing a version with partial hooks support ? latest release is from 10 Jun... 😢

Any news on releasing a version with partial hooks support ? latest release is from 10 Jun... 😢

believe it's blocked by facebook/react#15275

Is it safe to say that Enzyme Shallow still doesn't work on React Hooks?

@dschinkel no, because that suggests zero support - neither does it have full support.

I'm facing issues with .dive() method after upgrading to styled-components v5.0.0 and jest-styled-components v7.0.0 and it was working fine earlier before the upgrade.
The issue I'm facing is related to Hooks:

Invariant Violation: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
    1. You might have mismatching versions of React and the renderer (such as React DOM)
    2. You might be breaking the Rules of Hooks
    3. You might have more than one copy of React in the same app
    See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.

Do we not have support for hooks with .dive()? Any help would be appreciated @chenesan @ljharb

As far as I'm aware, they should work the same in .dive() as they do in shallow(), since that's all it does.

@ljharb Correction - I'm facing issues with .dive() as well as .shallow() after upgrading to styled-components v5.0.0 and jest-styled-components v7.0.0.
Anyone else facing similar issue?
Any suggestions how to fix this?

What changed in the underlying implementation in v5 versus v4?

@ljharb As per the styled components changelog (https://github.com/styled-components/styled-components/blob/master/CHANGELOG.md#v500---2020-01-13), there seems to be no mention in relation to hooks. I'm not sure of what might be causing the issue.

Clicking on styled-components/styled-components@v4.4.1...v5.0.0, however, shows a commit called "reimplement using hooks", so it's likely that this is the issue.

This PR suggests useState works with the shallow API.. a few of us are seeing that's not the case here. Can someone please clarify?

useEffect (Test case PR #2034 #2041 ; Currently not work in shallow renderer, see facebook/react#15275)

This is currently marked as completed, but I am still getting a console.error when using mount with a useEffect hook.

"enzyme": "^3.11.0",
"react": "^16.13.1",

In my case, useEffect is handling a promise, and then updating the state of the component:

useEffect(() => {
    axios
      .get(`/users/${userId}`)
      .then(response => setFields(response.data.data.attributes))
      .catch(err => console.error('Failed to load user profile', err))
  }, [])

This is the error I get:

  console.error node_modules/react-dom/cjs/react-dom.development.js:88
    Warning: An update to ProfileFeature inside a test was not wrapped in act(...).
    
    When testing, code that causes React state updates should be wrapped into act(...):
    
    act(() => {
      /* fire events that update state */
    });
    /* assert on the output */
    
    This ensures that you're testing the behavior the user would see in the browser. Learn more at https://fb.me/react-wrap-tests-with-act
        in ProfileFeature (at ProfileFeature.spec.js:41)
        in Router (at ProfileFeature.spec.js:40)
        in Provider (created by WrapperComponent)
        in WrapperComponent

Is this something on your radar? Or am I doing something incorrectly?

I will post a summary for those that came across this issue because of the problem with shallow renderer in enzyme.

The issue from facebook/react#15275 is not completed as mentioned in the comment above, it was just closed because of facebook/react#17321.

Issue facebook/react#17321 is closed as well, because as a outcome the react-shallow-renderer was extracted so that it is no longer part of the react project so that it can be enhanced/developed independently from the react team.

It seems that the project is now located under https://github.com/NMinhNguyen/react-shallow-renderer.
In addition there is a issue (enzymejs/react-shallow-renderer#16) in this new project, asking to transfer the shallow renderer into the github enzyme org.

Hopefully I summarized that correctly. For more, detailed or maybe more correct information, have a look on the linked issues/projects.

Continuing on @jzipfler 's summary.

The problem still remains that we can't test the public API of a React Hook (custom methods we choose to carefully expose to be part of it) via shallow render. People can't test off instance() which a lot of us do, and found solid ways to do that safely. There's a huge bandwagon of "don't test implementation details" and that is such a vague and misunderstood concept. Testing implementation details is relative to how you're writing your tests and your components and many of us, prefer not to be forced to test always through heavy imperative Shell (DOM wiring and events) just to gain confidence and design feedback especially when we TDD and code very leanly.

The Second problem is we shouldn't have to rely on Jest as a hack to get around shallow shortcomings. I come from a land where mocking everything is a big smell. Mocking Angular via TestBed, enough said. We should be able to test a lib like React with whatever testing framework we want. They keep forcing Jest mocking, etc. I don't wanna keep hearing that I must use Jest.

So for me, we're still forced to test everything through DOM wiring, which is not ideal for shallow. This is still not resolved really.

facebook/react#17321 (comment)

@dschinkel no, because that suggests zero support - neither does it have full support.

@ljharb We really need to know what exactly this means. What is supported, what does not zero actually mean? Is there a checklist that thoroughly explains the what and gaps in the current version of enzyme rather than try to guess here? Can we be a little more detailed here?

I probably won't give up on this until someone finds a way to either push React or work on a way that allows you to truly test under the skin with React Hooks. I personally don't have time to contribute on a whole new repo to do so.

I see many people only mentions shallow. Are hooks supposed to work with mount? If so, what are the requirements? I am getting react errors for almost every test where any of the nested components uses any hook (useEffect, useState, etc).
Are there any guidelines or requirements on how to test components that contain hooks?