tgriesser / cypress-graphql-mock

Adds commands for executing a mocked GraphQL server using only the client
171 stars 43 forks source link

Using graphql-tools' MockList sometimes results in errors. #11

Open DFurnes opened 5 years ago

DFurnes commented 5 years ago

I ran into a spooky issue when using graphql-tools' MockList to mock lists in my schema, where as soon as I returned a MockList in my mocks or operations object, I'd get an error like this:

GraphQL error: Expected Iterable, but did not find one for field Query.things.

Here's an example Cypress test snippet that reproduces this error:

import schema from '../schema.json';
import { MockList } from 'graphql-tools';

describe('Example', () => {
  beforeEach(() => cy.mockGraphql({ schema }));

  it('Results in an error', () => {
    cy.mockGraphqlOps({
      operations: {
        ExampleQuery: {
          things: [], // returning an empty array works fine...
        },
        AnotherExampleQuery: {
          things: new MockList(9), // but this doesn't!
        },
      },
    });

The error above gets thrown here, because the result instanceof MockList condition always returns false when trying to build the mocked GraphQL response (even though logging result to the console clearly shows it as a MockList).

I believe this is an issue with objects that "travel" between the main Cypress test runner & the actual page via the window:before:load event or the invoke command, since using instanceof to compare objects created in a different window will always return false. (See also: similar issues described in cypress-io/cypress#3420 and cypress-io/cypress#2794.)

DFurnes commented 5 years ago

I was able to work around this issue by creating my own simple MockList replacement that just works as a function (and so graphql-tools doesn't need to conditionally call .mock() on the object):

/**
 * Return a list of N items for a field, with an optional
 * list of field overrides for the items in the list.
 *
 * @param {Number} count
 * @param {Object} overrides
 */
function mockList(count, overrides = {}) {
  return new Array(count).fill().map(() => overrides);
}

Since this is a relatively unique problem to using a graphql-tools mocked schema within Cypress, it might make sense to include something similar in this library as a suggested workaround?