miragejs / graphql

A library for handling GraphQL requests with Mirage JS
MIT License
74 stars 12 forks source link

[QUESTION] Does this plugin works for testing? #64

Closed Freire71 closed 1 year ago

Freire71 commented 1 year ago

Hello, I was trying to set MirageJS in a React Native App, for development it works great, but I could not figure out how to make it works on test files. Is this plugin designed only for development? On my small test example my query never finishes the load state

image
jneurock commented 1 year ago

Hi. You can use this with any environment, including testing. I couldn't say why it's not working for you but it should be entirely possible.

Freire71 commented 1 year ago

Thanks @jneurock, unfortanely I've found no examples for GraphQL testing using MirageJS. Examples that do exists shows only it being used in development. I've created a REST test application and I could manage to make it work in both scenarios but with the GraphQL plugin it only works for me in development. I've created this repo where I have both strategies https://github.com/Freire71/React-Native-Data-Fetch-Mock

jneurock commented 1 year ago

I'll check that out. This library itself uses Mirage for testing. Maybe you can take a look at the test setup and see if there's something helpful in there in the meantime?

jneurock commented 1 year ago

I've taken a little bit of a closer look and Mirage GraphQL is successfully receiving the query and resolving it but I don't know Apollo well enough to guess why useQuery gets stuck in a loading state.

Freire71 commented 1 year ago

Thanks for the answer @jneurock when I have some free time I will try to dig depper on that, it seems a great tool to support both development and testing

Freire71 commented 1 year ago

@jneurock I've tried creating a react web example using create react app and the same stack of technologies (apollo included) and it all worked, Apollo resolves the query successfully. It may be a React Native specific issue. It could be related to some missing information on docs here: https://miragejs.com/quickstarts/react-native/react-native-testing-library/ Current test state is: react web + graphql - works, react native + rest - works, react native + graphql - does not works

jneurock commented 1 year ago

That is super interesting but also sounds frustrating. I wish I could be of more help. Hopefully, you have a good testing alternative for React Native?

Freire71 commented 1 year ago

Doing some testing I think that docs need to explain how to make Apollo fetch to be intercepted by MirageJS in a node environment. Just a remember: everything works in dev environment This an example of how create an Apollo client

new ApolloClient({
  cache: new InMemoryCache(),
  link: new HttpLink({
    uri: LOCAL_URL,
    fetch,
  }),
});

React Native do exposes the fetch api: https://reactnative.dev/docs/network but it seems that we are missing some information about how to combine miragejs + graphql + fetch polyfill on node I've tried importing some libraries like whatwg-fetch or cross-fetch on jest.setup.js file but my requests are still in a loading state. But if I do import cross-fetch/polyfill to this file, my requests starts to hit the real api If I try to create an instance of apollo client using cross-fetch my request are also not intercepted request to http://localhost:3000/graphql failed, reason: connect ECONNREFUSED 127.0.0.1:3000'

new ApolloClient({
  cache: new InMemoryCache(),
  link: new HttpLink({
    uri: LOCAL_URL,
    fetch: crossFetch,
  }),
});
Freire71 commented 1 year ago

I can still use ApolloMockedProvider or MSW Library to unit test my components but I would like to take advantage of MirageJS capabilities

Freire71 commented 1 year ago

Some logging, at my test scenario, both XMLHTTPRequest and Fetch are present and seems to be patched for testing, pretender is also there, adding some logging to Apollo it shows that it successfully receives my query but it does not receive an answer. I've also tested the same example with urql and graphql-request and it does not seem to have a major difference

image
Freire71 commented 1 year ago

Hi @jneurock, I've found a solution: I've needed to add global.FormData = class FormData {} on jest.setup.js. This line of Pretender throws because FormData in undefined whatwg-fetch is used because Apollo client is using the React Native implementation of fetch API but it does not exists for Node env. This my final version of the jest.setup.js file

import 'whatwg-fetch';
global.self = global;
global.XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest;
global.FormData = class FormData {};
jneurock commented 1 year ago

Oh wow. Impressive detective work! I imagine this could definitely help someone else. Very cool that you figured it out.

Freire71 commented 1 year ago

Closing this as I've found the solution, thanks!