vuejs / apollo

🚀 Apollo/GraphQL integration for VueJS
http://apollo.vuejs.org
MIT License
6.03k stars 523 forks source link

Unit test getting error when query have Reactive parameters(varibale) #1104

Open ksankumar opened 4 years ago

ksankumar commented 4 years ago

This is my gql Query

query Pokemons( $search: String){
 pokemons(query: {  search: $search} }) {
    edges {
      id
      name
      types
      image
      isFavorite
    }
  }
}

This is my vue component:

export default {
    name: "pokemons-list",
    data: () => ({
        searchText: "",
    }),
    apollo: {
        pokemons: {
            query: Pokemons,
            variables() {
                return {
                    "search": "test"
                };
            },
            fetchPolicy: "network-only",
            debounce: 300,
            loadingKey: "loading"
        },
        fetchLocalUser: {
            query: localTestQuery,
            result() {
                // eslint-disable-next-line no-console
                // console.log("*************Test fetched!");
            }
        }
    }
}

This is my unit test

import { shallowMount, createLocalVue } from "@vue/test-utils";
import Vue from "vue";
import VueApollo from "vue-apollo";
import Vuetify from "vuetify";
import ListComponent from '@/views/List.vue'

import { createMockClient } from "mock-apollo-client";
import pokemonsQuery from "@/graphql/pokemons.query.gql";
import localTestQuery from "@/graphql/localTest.query.gql";

import VueRouter from "vue-router";
import PokemonsList from "@/views/List";

const newHeroMockResponse1 = {
    data: {
        pokemons: {
            edges: [{
                "id": "001",
                "name": "Bulbasaur",
                "types": ["Grass", "Poison"],
                "image": "",
                "isFavorite": false
            }, {
                "id": "002",
                "name": "Bulbasaur",
                "types": ["Grass", "Poison"],
                "image": "",
                "isFavorite": false
            }]
        }
    }
}

const localVue = createLocalVue();

// let wrapper
const routes = [{ path: "/", name: "PokemonsList", component: PokemonsList }];
const router = new VueRouter({ routes });

Vue.use(VueRouter);
Vue.use(Vuetify);
Vue.use(VueApollo);

describe("App component", () => {
    let wrapper;
    let mockClient;
    let apolloProvider;
    let requestHandlers;

    const createComponent = (handlers, data) => {
        // We want to specify default handlers for different operations and overwrite them with passed handlers
        requestHandlers = {
            allPokeyMonsQueryHandler: jest.fn().mockResolvedValue(newHeroMockResponse1),
            ...handlers
        };

        mockClient = createMockClient({
            resolvers: {}
        });

        mockClient.cache.writeQuery({
            query: localTestQuery,
            data: {
                fetchLocalUser: {
                    __typename: "User",
                    name: "Test"
                }
            }
        });

        // Unfortunately, it's not possible to override handler already set
        // So we need to do all the work for setting handlers in the factory
        mockClient.setRequestHandler(
            pokemonsQuery,
            requestHandlers.allPokeyMonsQueryHandler
        );

        apolloProvider = new VueApollo({
            defaultClient: mockClient
        });
        wrapper = shallowMount(ListComponent, {
            localVue,
            apolloProvider,
            router,
            data() {
                return {
                    ...data
                };
            }
        });
    };

    afterEach(() => {
        wrapper.destroy();
        mockClient = null;
        apolloProvider = null;
    });

    const obj = {
        "search": ""
    };
    it("renders a loading block when query is in progress", () => {
        createComponent({}, obj);
        expect(requestHandlers.allPokeyMonsQueryHandler).toHaveBeenCalledWith(obj);
    });
});

Error: FAIL tests/unit/lists.spec.js App component ✕ renders a loading block when query is in progress (24ms)

● App component › renders a loading block when query is in progress

expect(jest.fn()).toHaveBeenCalledWith(...expected)

Expected: {"search": ""}

Number of calls: 0

  106 |     it("renders a loading block when query is in progress", () => {
  107 |         createComponent({}, obj);
> 108 |         expect(requestHandlers.allPokeyMonsQueryHandler).toHaveBeenCalledWith(obj);
      |                                                          ^
  109 |     });
  110 | });

  at Object.<anonymous> (tests/unit/lists.spec.js:108:58)
JuroOravec commented 4 years ago

Have you tried adding some waiting, e.g. await new Promise(res => setTimeout(res, 200))? Maybe you just need to wait a few ticks for the value to load. Otherwise, I wonder if it's the same issue as what I describe here https://github.com/vuejs/vue-apollo/issues/951#issuecomment-732150593