Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MockedProvider not returning data when @client is specified #4532

Closed
nicoladj77 opened this issue Mar 3, 2019 · 18 comments · Fixed by #9867
Closed

MockedProvider not returning data when @client is specified #4532

nicoladj77 opened this issue Mar 3, 2019 · 18 comments · Fixed by #9867
Assignees

Comments

@nicoladj77
Copy link

I didn't know if I should open a new issue or if I should have commented on #4325

Intended outcome:
Writing a MockedProvider for a query only with @client directives should return data

Actual outcome:
No data is returned when the test is run.

How to reproduce the issue:
My test:

const mockLocal = () => [
  {
    request: {
      query: GET_STATE,
      variables: {},
    },
    result: {
      data: {
        renderType: 'default',
        path: '',
        staticContent: {
          navigation: {
            links: [
              {to: '/article', text: 'Article'},
              {to: '/home', text: 'Home'}
            ]
          },
          header: {
            logo: ''
          }
        }
      }
    },
  },
];

describe('<Html>', () => {
  it('renders correctly', async () => {
    const tree = renderer
    .create(<MockedProvider mocks={mockLocal()} addTypename={false}><Router><Navigation/></Router></MockedProvider>)
    .toJSON();
    await wait(0);
    expect(tree).toMatchSnapshot();
  });
});

My query:

export const GET_STATE = gql`
  {
    renderType @client,
    path @client,
    staticContent @client {
      navigation @client {
        links @client {
          to,
          text
        }
      }
     header @client {
        logo
      }
    }
  }
`;

The issue is that when I run the mock, and I console.log in the component that uses the query, the result is an empty object instead of what I specified in result.data

Versions
System:
OS: Windows 10
Binaries:
Node: 11.4.0 - C:\Program Files\nodejs\node.EXE
Yarn: 1.13.0 - C:\Program Files (x86)\Yarn\bin\yarn.CMD
npm: 6.4.1 - C:\Program Files\nodejs\npm.CMD
Browsers:
Edge: 42.17134.1.0
npmPackages:
apollo-client: ^2.5.1 => 2.5.1
react-apollo: ^2.5.1 => 2.5.1

@hwillson hwillson self-assigned this Mar 3, 2019
@hwillson
Copy link
Member

hwillson commented Mar 3, 2019

Thanks @nicoladj77 - let's keep this as its own issue for now, but I'll be addressing this and #4325 at the same time.

@simonedavico
Copy link

Is there any ETA on this? I am relying on @client state for a few critical app components that I can't test right now :\

Don't want to put you in a hurry, I just want to know if I have to think about some alternative strategy for testing instead of waiting for a fix.

@gcornhill
Copy link

Hi @hwillson , @simonedavico - Any updates on this? Running into same problem as above.
Thanks!

@andymrussell
Copy link

+1

@hwillson hwillson removed their assignment Aug 7, 2019
@pdemarino
Copy link

+1

@pdemarino
Copy link

pdemarino commented Aug 20, 2019

This seems related to #4520

@dphaener
Copy link

Hey everyone. I'm running into the same issues here. I've gotten around this by not including the custom resolvers (which makes the test suite noisy with the apollo warning about client directives without resolvers, but hey) in the MockedProvider in conjunction with using the render and wait functions from @testing-library/react-native. Example:

const mocks = createMocks([{ isConnected: false, isPluggedIn: true }]);
const { container, getByText } = render({}, mocks);

await wait(() => {
  expect(toJSON(container)).toMatchSnapshot();
});

Where the render function is just a wrapper around creating the MockedProvider in an easy way. Hope this helps until this issue is properly resolved.

@leanne1
Copy link

leanne1 commented Nov 4, 2019

+1

@chrisbrooks
Copy link

chrisbrooks commented Nov 29, 2019

yeah same for me removing the resolvers from the mockProvider it works. Also make sure if you have __typename in the mocks.

import { MockedProvider } from '@apollo/react-testing';
import React from 'react';

import { updateWrapper } from 'utils/testUtils';

import GET_CARDS_LIST_SORTING from './graphql/getCardListSorting.graphql';
import { en } from './translations';
import { TableHeadings } from '.';

describe('TableBody', () => {
  const props = {
    strings: en,
  };

  const mocks = [
    {
      request: {
        query: GET_CARDS_LIST_SORTING,
      },
      result: {
        data: {
          cardsList: {
            sorting: {
              expiresIn: 'ASC',
              __typename: 'CardsListSorting',
            },
            __typename: 'CardsList',
          },
        },
        loading: false,
        error: null,
      },
    },
  ];

  it('matches snapshot', async () => {
    const wrapper = mount(
      <MockedProvider mocks={mocks} addTypename={false}>
        <TableHeadings {...props} />
      </MockedProvider>
    );

    await updateWrapper(wrapper);

    console.log(wrapper.debug());
  });
});

@axelnormand
Copy link

axelnormand commented Jan 5, 2020

I'm also getting this.
Removing the resolvers being added to MockedProvider makes the mocked queries work. However i get the annoying "Found @client directives in a query but no ApolloClient resolvers were specified." console warning.
Furthermore I wonder how to best to test components that use local mutations resolvers if they're not being added?

Do you think this bug will be fixed? Or should i be testing local apollo things differently?
Thanks

@mocantimoteidavid
Copy link

I'm still facing this issue too.
Maybe we could do it with the temporary workaround for now, but wanted to ask the same question - if any attention is being paid to this issue, or if anything new came up about it.
If it helps, I could also provide my case, but it's really not that different compared to what is already discussed.

@chris-mo
Copy link

Bump, 1.5 years later after the original poster!

Facing the same issue...

@hwillson
Copy link
Member

Please note that MockedProvider creates its own ApolloClient instance behind the scenes, like this:

const {
  mocks,
  addTypename,
  defaultOptions,
  cache,
  resolvers,
  link
} = this.props;
const client = new ApolloClient({
  cache: cache || new Cache({ addTypename }),
  defaultOptions,
  link: link || new MockLink(
    mocks || [],
    addTypename,
  ),
  resolvers,
});

This means that if you're using Apollo Client 2.x local resolvers, or Apollo Client 3.x type/field policies, you have to tell the MockedProvider component what you're going to do with @client fields. Otherwise the ApolloClient instance created behind the scenes doesn't know how handle things. In other words:

If using Apollo Client 2.x local resolvers, make sure your resolvers object is passed into MockedProvider:

<MockedProvider mocks={mocks} resolvers={resolvers} ...

If using Apollo Client 3.x type/field policies, make sure your configured cache instance (with your typePolicies) is passed into MockedProvider:

<MockedProvider mocks={mocks} cache={cache} ...

@chris-mo
Copy link

For my scenario, i'm not testing a mutation or any update to the local state. The component i'm testing just simply fetches some data from local state. I'm not following how passing in local resolvers would help here. Can you provide an example here?

@hwillson
Copy link
Member

hwillson commented Oct 29, 2020

@chris-mo The mocked data you pass into MockedProvider fakes out the data Apollo Client would get back through its Apollo Link chain. In other words it's faking out the data that would come back from making a request to a backend GraphQL API. @client fields are virtual fields, meaning they are never sent through the Link chain, and their data never comes back through the Link chain. In other words, to be able to test @client fields using MockedProvider, you have to provide the data behind them in some other manner, since you can't provide that data using something like mocks. There are different ways to do this, like providing your own resolvers to return the mocked @client data, or by using typePolicies and a cache instance to do the same thing. You can also write mock data for your @client fields into the cache directly using something like cache.writeQuery(), then make sure you pass that same cache instance into MockedProvider so it's used when your query runs.

@chris-mo
Copy link

chris-mo commented Oct 29, 2020

@hwillson thanks! I actually gave this a shot last night, which got rid of the error message mentioned above, but i must have some incorrect syntax as the data returned still returns as undefined

let's say i have the following query
query { state @client { someObject { someValue } } }

The resolver i have for this but seems incorrect is

const resolvers = {
   Query: {
         state() {
               return { ...}
         }

  } 
}

EDIT: I got it to work, just had to edit my return obj. Thanks for the response @hwillson

@youngrichard
Copy link

youngrichard commented Feb 27, 2021

@hwillson Thanks for the detailed explanation! That helped me better understand what's going on under the hood.

Unfortunately I'm still experiencing this issue. I have a query labeled with @client, which I am using in my React component, as well as in the the mockrequest. I'm passing an instance of my cache to MockedProvider, along with some mocks that I believe are the right shape. When the component renders, I'm able to hit a breakpoint in my typePolicies, however the data returned is still undefined.

Do you have any ideas of what I should look for?

FWIW I'm on "@apollo/client": "^3.2.5"

@jpvajda
Copy link
Contributor

jpvajda commented Jun 29, 2022

closing this issue as we did some documentation updates to account for local state testing. in #9867

@jpvajda jpvajda closed this as completed Jun 29, 2022
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 15, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.