1
votes

Is there a way to test functional components built using React hooks by shallow mounting the component. I came across Enzyme not supporting useEffect (https://airbnb.io/enzyme/#react-hooks-support) and other hooks with shallow rendering a component and I don’t want to get into mount.

Also came across react-testing-library being a new and popular alternative. Is it better option compared to Enzyme? I already have Enzyme used for testing class based components. So, there is a pain involved in rewriting those.

1
Any reason why you do not want to fully render it? Even though it is troublesome to use mount (especially if you are rendering a connected component), I still think it is the most straight forward way to test its behaviourwentjun
@wentjun I would like to separately test each component as a unit hence shallow is what I prefer.JS dev
Ahh I see.. Makes sense. I would have preferred shallow rendering in that scenario as well.wentjun

1 Answers

3
votes

Yes you can but will need to use spies. For example if you are using jest you can you use jest.spyOn with mockImplementationOnce(), It should also work with other spying libraries.

Using Example:

describe("React useEffect", () => {
  let useEffect, wrapper

  let mockUseEffect = () => {
    useEffect.mockImplementationOnce(f => f())
  }

  beforeEach(() => {
    useEffect = jest.spyOn(React, "useEffect")

    mockUseEffect()
    wrapper = shallow(<SomeComponent />)
  })

  it("your test", () => {
     // using wrapper
  })
}

Here is a nice detailed article by "Will Ockelmann-Wagner" and I added a codeSandbox working example.


Although it works, I'd encourage you to not use shallow rendering and start using react-testing-library (called @testing-library/react nowadays), Its well-documented, lightweight Testing solution, and I'd say its the the "closest" test you can get to real world scenarios. It comes already with CRA by default.

Here a basic codeSandbox example and Here is more examples from React Docs.

Also, here is a great Video by Kent C. Dodds that addressing the differences between shallow rendering and the render approach from react testing library.