Graphql-tools: Using preserveResolvers with true value, mock resolvers are executed even with real resolvers being declared

Created on 9 Jan 2017  路  4Comments  路  Source: ardatan/graphql-tools

Hi! :)

Maybe I'm missing something, but when I set preserveResolvers: true in addMockFunctionsToSchema it's expected to override mock resolvers, only if the real resolvers aren't declared.

From the docs:

If preserveResolvers is set to true, existing resolve functions will not be overwritten to provide mock data. This can be used to mock some parts of the server and not others.

Is this a bug? if so, could someone point me into the right direction to fix this? this features is a real need on our dev workflow, because I'll like to have the mock workin only when the real resolver exist, and I set preserveResolvers: true.

thanks!

Most helpful comment

I would like to reopen this issue as @sebas5384 is right about the addMockFunctionsToSchema function. It's not working in a way one would expect however it seems to work like it's described in docs. However, I would like to illustrate the problem with this simple example:

// resolvers.js
import _get from "lodash/get";
import createPatient from "./mutations/createPatient";

const resolvers = {
  Patient: {
    id: (user, args, context) => {
      console.log("[RESOLVE] Patient.id");
      return _get(user, "_id");
    },
    firstName: (user, args, context) => {
      console.log("[RESOLVE] Patient.firstName");
      return _get(user, "profile.firstName");
    },
    lastName: (user, args, context) => {
      console.log("[RESOLVE] Patient.lastName");
      return _get(user, "profile.lastName");
    }
  },
  Query: {
    patient: (root, args, context) => {
      console.log("[RESOLVE] Query.patient");
      return context.loaders.patients.load(_get(args, "id"));
    }
  },
  Mutation: {
    createPatient: async (root, args, context) => {
      return createPatient(args);
    }
  }
};

export default resolvers;
// mocks.js
import casual from "./casual";

const mocks = {
  Query: () => ({
    patient: (root, args, context) => {
      console.log("[MOCK] Query.patient");
      return casual.user(args.id);
    }
  })
};

export default mocks;

Logs for addMockFunctionsToSchema({ schema, mocks });:

[MOCK] Query.patient

Logs for addMockFunctionsToSchema({ schema, mocks, preserveResolvers: true });:

[MOCK] Query.patient
[RESOLVE] Query.patient // and it crashes here but this line should never be called

The problem is that I've overridden Query.patient with the mock function and I would expect the original resolve function to never be called.

Is it possible to provide all resolvers and only mock some types and other not mocked leave to resolvers?

All 4 comments

@sebas5384 with preserveResolvers:true addMockFunctionsToSchema will not overwrite any existing resolvers, but only add resovlers where none exist. Is that not the behavior you're seeing?

Closing this for lack of activity

I would like to reopen this issue as @sebas5384 is right about the addMockFunctionsToSchema function. It's not working in a way one would expect however it seems to work like it's described in docs. However, I would like to illustrate the problem with this simple example:

// resolvers.js
import _get from "lodash/get";
import createPatient from "./mutations/createPatient";

const resolvers = {
  Patient: {
    id: (user, args, context) => {
      console.log("[RESOLVE] Patient.id");
      return _get(user, "_id");
    },
    firstName: (user, args, context) => {
      console.log("[RESOLVE] Patient.firstName");
      return _get(user, "profile.firstName");
    },
    lastName: (user, args, context) => {
      console.log("[RESOLVE] Patient.lastName");
      return _get(user, "profile.lastName");
    }
  },
  Query: {
    patient: (root, args, context) => {
      console.log("[RESOLVE] Query.patient");
      return context.loaders.patients.load(_get(args, "id"));
    }
  },
  Mutation: {
    createPatient: async (root, args, context) => {
      return createPatient(args);
    }
  }
};

export default resolvers;
// mocks.js
import casual from "./casual";

const mocks = {
  Query: () => ({
    patient: (root, args, context) => {
      console.log("[MOCK] Query.patient");
      return casual.user(args.id);
    }
  })
};

export default mocks;

Logs for addMockFunctionsToSchema({ schema, mocks });:

[MOCK] Query.patient

Logs for addMockFunctionsToSchema({ schema, mocks, preserveResolvers: true });:

[MOCK] Query.patient
[RESOLVE] Query.patient // and it crashes here but this line should never be called

The problem is that I've overridden Query.patient with the mock function and I would expect the original resolve function to never be called.

Is it possible to provide all resolvers and only mock some types and other not mocked leave to resolvers?

I spend over two hours trying figure out why mocks were being called when I had a resolver; it wasn't until I commented out this line:
// addMockFunctionsToSchema({schema: executableSchema, mocks, preserveResolvers: true})
that my resolver appeared!

    "graphql-tools": "^2.21.0",
Was this page helpful?
0 / 5 - 0 ratings

Related issues

flippidippi picture flippidippi  路  3Comments

benjaminhon picture benjaminhon  路  3Comments

BassT picture BassT  路  3Comments

capaj picture capaj  路  4Comments

tonyxiao picture tonyxiao  路  4Comments