Skip to content
This repository was archived by the owner on Jul 30, 2020. It is now read-only.

query does not work in react-native and apollo #119

Closed
augus-zz opened this issue Apr 8, 2020 · 3 comments
Closed

query does not work in react-native and apollo #119

augus-zz opened this issue Apr 8, 2020 · 3 comments

Comments

@augus-zz
Copy link

augus-zz commented Apr 8, 2020

  • react-native:
  • native-testing-library version: 5.0.3
  • jest-preset:
  • react-native version: 0.61.5
  • node version: v10.19.0

Relevant code or config:

import React from 'react'
import gql from 'graphql-tag'
import { useQuery } from '@apollo/react-hooks'
import { MockedProvider } from '@apollo/react-testing'
import wait from 'waait'
import { render } from '@testing-library/react-native'

// Make sure the query is also exported -- not just the component
const GET_DOG_QUERY = gql`
  query getDog($name: String) {
    dog(name: $name) {
      id
      name
      breed
    }
  }
`

const Dog: React.SFC<{ name: string }> = ({ name }) => {
  const {
    loading, error, data,
  } = useQuery(GET_DOG_QUERY, { variables: { name } })
  if (loading) return <p>Loading...</p>
  if (error) return <p>Error!</p>

  return <p>{`${data.dog.name} is a ${data.dog.breed}`}</p>
}

describe('verify apollo', () => {
  it('render', async () => {
    const mocks = [
      {
        request: {
          query: GET_DOG_QUERY,
          variables: {
            name: 'Buck',
          },
        },
        result: {
          data: {
            dog: {
              id: '1',
              name: 'Buck',
              breed: 'bulldog',
            },
          },
        },
      },
    ]

    const {
      queryByText, debug,
    } = render(
      <MockedProvider
        mocks={mocks}
        addTypename={false}
      >
        <Dog name='Buck' />
      </MockedProvider>,
    )
    debug()
    const loading = queryByText(/Loading/i)
    expect(loading).not.toBeNull()

    await wait(0) // wait for response

    debug()
    expect(queryByText('Buck is a bulldog')).toBeTruthy()
  })
})

What you did:

setup a test to verify demo from https://www.apollographql.com/docs/react/development-testing/testing/

What happened:

failed to query text Loading... in render result

Problem description:

yarn test tests/__tests__/setup.spec.tsx
yarn run v1.22.0
$ node --max-old-space-size=4096 ./node_modules/.bin/jest --maxWorkers 2 --forceExit --ci --detectOpenHandles tests/__tests__/setup.spec.tsx
 FAIL  tests/__tests__/setup.spec.tsx
  verify apollo
    ✕ render (41ms)

  ● verify apollo › render

    expect(received).not.toBeNull()

    Received: null

      61 |     debug()
      62 |     const loading = queryByText(/Loading/i)
    > 63 |     expect(loading).not.toBeNull()
         |                         ^
      64 |
      65 |     await wait(0) // wait for response
      66 |

      at toBeNull (tests/__tests__/setup.spec.tsx:63:25)
      at tryCatch (node_modules/regenerator-runtime/runtime.js:45:40)
      at Generator.invoke [as _invoke] (node_modules/regenerator-runtime/runtime.js:271:22)
      at Generator.prototype.(anonymous function) [as next] (node_modules/regenerator-runtime/runtime.js:97:21)
      at tryCatch (node_modules/regenerator-runtime/runtime.js:45:40)
      at invoke (node_modules/regenerator-runtime/runtime.js:135:20)
      at node_modules/regenerator-runtime/runtime.js:170:11
      at tryCallTwo (node_modules/promise/lib/core.js:45:5)
      at doResolve (node_modules/promise/lib/core.js:200:13)
      at new Promise (node_modules/promise/lib/core.js:66:3)

  console.log node_modules/@testing-library/react-native/dist/index.js:106
    <View
      pointerEvents="box-none"
      style={
        Object {
          "flex": 1,
        }
      }
    >
      <View
        collapsable={true}
        pointerEvents="box-none"
        style={
          Object {
            "flex": 1,
          }
        }
      >
        <p>
          Loading...
        </p>
      </View>
    </View>

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        2.997s
Ran all test suites matching /tests\/__tests__\/setup.spec.tsx/i.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
$ yarn test tests/__tests__/setup.spec.tsx
yarn run v1.22.0
$ node --max-old-space-size=4096 ./node_modules/.bin/jest --maxWorkers 2 --forceExit --ci --detectOpenHandles tests/__tests__/setup.spec.tsx
 FAIL  tests/__tests__/setup.spec.tsx
  verify apollo
    ✕ render (46ms)

  ● verify apollo › render

    expect(received).not.toBeNull()

    Received: null

      65 |       normalizer: getDefaultNormalizer({ trim: false }),
      66 |     })
    > 67 |     expect(loading).not.toBeNull()
         |                         ^
      68 |
      69 |     await wait(0) // wait for response
      70 |

      at toBeNull (tests/__tests__/setup.spec.tsx:67:25)
      at tryCatch (node_modules/regenerator-runtime/runtime.js:45:40)
      at Generator.invoke [as _invoke] (node_modules/regenerator-runtime/runtime.js:271:22)
      at Generator.prototype.(anonymous function) [as next] (node_modules/regenerator-runtime/runtime.js:97:21)
      at tryCatch (node_modules/regenerator-runtime/runtime.js:45:40)
      at invoke (node_modules/regenerator-runtime/runtime.js:135:20)
      at node_modules/regenerator-runtime/runtime.js:170:11
      at tryCallTwo (node_modules/promise/lib/core.js:45:5)
      at doResolve (node_modules/promise/lib/core.js:200:13)
      at new Promise (node_modules/promise/lib/core.js:66:3)

  console.log node_modules/@testing-library/react-native/dist/index.js:106
    <View
      pointerEvents="box-none"
      style={
        Object {
          "flex": 1,
        }
      }
    >
      <View
        collapsable={true}
        pointerEvents="box-none"
        style={
          Object {
            "flex": 1,
          }
        }
      >
        <p>
          Loading...
        </p>
      </View>
    </View>

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        5.038s
Ran all test suites matching /tests\/__tests__\/setup.spec.tsx/i.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

from debug output. we could see Loading...

@augus-zz
Copy link
Author

augus-zz commented Apr 8, 2020

#63 dup

@augus-zz augus-zz closed this as completed Apr 8, 2020
@andrico1234
Copy link

This doesn't look like a duplicate because the underlying issue that you're having isn't the getByText not working, it's the await wait(0) not causing your Apollo query/mutation to update with the mock data.

I'm in the same boat, and would love to know how people have gotten this working in RN

@andrico1234
Copy link

andrico1234 commented Apr 16, 2020

I managed to get things working.

Because I was setting the timers: fake in the jest.config file, it was causing await wait(0) to not behave correctly.

I added jest.useRealTimers() at the top of the test, and everything worked a treat.

this is what my test looks like

import React from "react";
import { gql } from "react-apollo";
import { render, fireEvent, act } from "@testing-library/react-native";
import wait from "waait";
import { MockedProvider } from "@apollo/react-testing";
import UpdateEmailForm from "../updateEmailForm";

const UPDATE_EMAIL = gql`
    mutation UpdateEmail($email: String!) {
        updateEmail(email: $email) {
            newEmail
        }
    }
`;

const mocks = [
  {
    request: {
      query: UPDATE_EMAIL,
      variables: {
        email: "[email protected]"
      }
    },
    result: {
      data: {
        updateEmail: {
          newEmail: "[email protected]"
        }
      }
    }
  }
];

function renderComponent() {
  function Component() {
    return (
      <MockedProvider mocks={mocks} addTypename={false}>
          <UpdateEmailForm componentId="1234" />
      </MockedProvider>
    );
  }

  return render(<Component />);
}

describe("UpdateEmailForm", () => {
  it("should update my email", async () => {
    jest.useRealTimers();

    const { getByPlaceholderText, getByText, queryByText } = renderComponent();

    const emailInput = getByPlaceholderText("Email");
    const sendLinkButton = getByText("update my email");

    fireEvent.changeText(emailInput, "[email protected]");
    fireEvent.pressOut(sendLinkButton);

    await act(async () => {
      await wait(0);
    });
    
    expect(queryByText(/Email successfully updated/)).toBeTruthy();
  });
});

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants