jarwin
jarwin

Reputation: 668

How to use jest.spyOn with react testing library

I'm refactoring a class component to a functional component.

In my test file I was using enzyme, but I'm migrating to react-testing-library

This the test I'm doing using enzyme

it('should change module when clicked button login', () => {
     const wrapper = mount(<SignUp setModuleCallback={jest.fn()} />)
     const instance = wrapper.instance()

     jest.spyOn(instance, 'setModule')
     wrapper.find('button#login-button').simulate('click')

     expect(instance.setModule).toHaveBeenCalled()
   })

And this is what I'm trying to do using react-testing-library

it('should change module when clicked button login', async () => {
     const { getByTestId } = render(<SignUp setModuleCallback={jest.fn()} />)
     const instance = getByTestId('submit')

     jest.spyOn(instance, 'setModule')

     const button = await waitFor(() => getByTestId('submit'))

     act(() => {
       fireEvent.click(button)
     })

     expect(instance.setModule).toHaveBeenCalled()
   })

Here's the error that i'm getting

enter image description here

Upvotes: 8

Views: 15220

Answers (1)

srk
srk

Reputation: 1901

The philosophy behind RTL is that you should test your components "the way your software is used." With that in mind, is there a way to test your component without explicitly asserting that the callback was invoked?

According to your test name, you expect some "module to change." Is there some way to verify in the DOM that the module was changed? For example, maybe each "module" has a unique title, in which case you could use screen.getByText to assert that the correct module is rendered after clicking the button.

If you want to explicitly assert that a callback function was invoked, are you sure you have to use spyOn for this test? I would try something like this:

it('should change module when clicked button login', async () => {
  const mockCallback = jest.fn()
  const { getByTestId } = render(<SignUp setModuleCallback={mockCallback} />)

  const button = await waitFor(() => getByTestId('submit'))

  act(() => {
    fireEvent.click(button)
  })

  expect(mockCallback).toHaveBeenCalled()
})

Upvotes: 7

Related Questions