question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

onError is not called when using testing-library/react-hooks

See original GitHub issue

Intended outcome: I am writing a custom hook using Apollo React hooks, setting onError to do console.error if an error occurs, but otherwise only dealing with successful data. I then want to test the error state of the custom hook using renderHook from @testing-library/react-hooks and MockedProvider. I would expect onError to be called if an error occurs, with the same value as the error key in the useQuery result.

Actual outcome: onError is never actually called

How to reproduce the issue: The following jest test fails on the last assertion on onErrorData

import { useQuery } from '@apollo/react-hooks'
import { MockedProvider } from '@apollo/react-testing'
import { act, renderHook } from '@testing-library/react-hooks'
import gql from 'graphql-tag'
import _ from 'lodash'
import React, { useState } from 'react'

type MyQuery = {
  name: string
}

const MyQueryDocument = gql`
  query {
    name
  }
`

const useFoo = () => {
  const [onErrorData, setOnErrorData] = useState()
  const { data, error } = useQuery<MyQuery>(MyQueryDocument, {
    onError: setOnErrorData
  })

  return { data, error, onErrorData }
}

test('onError should be called', async () => {
  const mocks = [
    {
      request: {
        query: MyQueryDocument,
      },
      error: new Error('this is an error'),
    },
  ]

  const { result } = renderHook(() => useFoo(), {
    wrapper: ({ children }) => (
      <MockedProvider mocks={mocks}>
        <>{children}</>
      </MockedProvider>
    )
  })

  await act(() => new Promise(_.defer))

  expect(result.current.data).toBeUndefined()
  expect(result.current.error?.message).toBe('Network error: this is an error')
  expect(result.current.onErrorData?.message).toBe('Network error: this is an error')
})

Versions

  System:
    OS: macOS Mojave 10.14.6
  Binaries:
    Node: 13.11.0 - /usr/local/bin/node
    Yarn: 1.22.4 - ~/leapyear/lyalpha/node_modules/.bin/yarn
    npm: 6.13.7 - /usr/local/bin/npm
  Browsers:
    Chrome: 80.0.3987.163
    Firefox: 72.0.2
    Safari: 13.1

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:9
  • Comments:11

github_iconTop GitHub Comments

2reactions
jonathanfilbertcommented, May 23, 2022

For everyone still looking for an answer. This works for me. Make sure to NOT include the error inside of the result key in the mock.

So instead of writing:

export const mock = (errorMessage: string) => {
  return {
    request: {
      ...
    },
result: {
    errors: [new GraphQLError(errorMessage)],
},
  };
};

Turn it to:

export const mock = (errorMessage: string) => {
  return {
    request: {
      ...
    },
    errors: [new GraphQLError(errorMessage)],
  };
};

Then, and only then, your onError callback will get invoked during the tests.

Cheers! 🥳

0reactions
zebapycommented, Aug 22, 2022

☝️ ☝️ ☝️ This may not be ideal for your test cases.

You’re setting the network response error when some may want to test graphql errors

It results in an error like:

graphQLErrors: [],
networkError: GraphQLError [Object] {
  message: 'my error message',
  extensions: [Object]
},

This makes my implementation for onError not work because I want to handle graphql errors, not network errors


  function onError(error?: ApolloError) {

    if (!error?.graphQLErrors.length) {
      return;
    }

    const err = error.graphQLErrors[0];

    if (err.extensions?.code === "CONFLICT") {
      setErrors(...);
    } 

  }

Read more comments on GitHub >

github_iconTop Results From Across the Web

Test useRef onError Fn, with React-Testing-Library and Jest
The Problem: I want to test that my onerror function has been called exactly one time. Which I am really stuck on how...
Read more >
onError is not called when using testing-library/react-hooks
Intended outcome: I am writing a custom hook using Apollo React hooks, setting onError to do console.error if an error occurs, but otherwise...
Read more >
Testing React components - Apollo GraphQL Docs
This article describes best practices for testing React components that use Apollo Client. The examples below use Jest and React Testing Library, ...
Read more >
Invalid Hook Call Warning - React
You might be using a version of react-dom (< 16.8.0) or react-native (< 0.59) that doesn't yet support Hooks. You can run npm...
Read more >
react-dropzone
Simple React hook to create a HTML5-compliant drag'n'drop zone for files. ... NOTE: using Enzyme for testing is not supported at the moment,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found