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

[Feature request] Mocking: access generated mock objects for individual queries and mutations #1682

Closed
alexstrat opened this issue Jun 23, 2020 · 3 comments
Labels
feature New addition or enhancement to existing solutions

Comments

@alexstrat
Copy link
Contributor

alexstrat commented Jun 23, 2020

I'm trying to use mocking to build a front-end where the backend is not yet ready, but
I'm struggling going beyond basic usage. I explain the problem and suggest a feature to solve it:

Problem

As example let's take this schema:

type Todo {
  id: Int!
  title: String!
  description: String
}

type Query {
  myTodos: [Todo!]!
  todoById(todoId:  Int!): Todo!
}

type Mutation {
  changeTodoTitle(todoId:  Int!, newTitle: String!): Todo!
}

And these operations:

query GetMyTodosForAList {
  myTodos {
    id,
    title
  }
}

query GetATodoForDetailView($todoId: Int!) {
  todoById(todoId: $todoId) {
    id
    title
    description
  }
}

mutation ChangeTodoTitle($todoId: Int!, $newTitle: String!) {
  changeTodoTitle(todoId:  $todoId, newTitle: $newTitle): {
    id
    title
  }
}

Like in the doc example, without almost 0 effort, it's very easy to mock GetMyTodosForAList that, as example, returns 2 todos: { id: 1, title: 'Title 1'}, { id: 2, ...}.

But calling GetATodoForDetailView with todoId=1 returns a todo with a different id and a different title than the one from GetMyTodosForAList with id=1. That's normal but, obviously, that's not what a normal schema would do and it leads to unusable behavior on the front-end.

Same thing happens when calling ChangeTodoTitle for Todo with id=1. Here, one can easily mock changeTodoTitle to return { id: 1, title: newTitle}, ie what a normal schema would do. But, when calling GetATodoForDetailView (by example to update the view after a mutation), a new random title will appear.

With a bit of work, these issues can be worked around, for instance by manually generating a kind of TODOS_STORE and query / update it, but I feel like that's a job that apollo-tools mocking can help the user with.

Solution: state-full mocks

It relies on the introduction of a MockStore that'll get populated with generated mocks and exposes 2 public methods:

  • get(typeName: string, id: string | int) to query it
  • update(typeName: string, id: string | int, newValue: any) to update it

This store would be accessible via the context argument in mock functions:

Example usage:

addMocksToSchema({
  schema,
  Query: () => ({
    todoById: (_, { todoId }, { __mockStore }) => __mockStore.get('Todo', todoId)
  }),
  Mutation: () => ({
    changeTodoTitle:  (_, { todoId, newTitle }, { __mockStore }) => __mockStore.update('Todo', todoId, { title:  newTitle })
  })
});
@ardatan ardatan added the feature New addition or enhancement to existing solutions label Jun 23, 2020
@alexstrat
Copy link
Contributor Author

alexstrat commented Jul 27, 2020

I've pursued the idea I proposed above and implemented it in graphql-stateful-mock.

It provides solutions for the problems exposed above and others I stumbled upon along the path of mocking a schema with better realism. You can find the solutions in the recipes section of the README.

The common parts of the API are very close to @graphql-tools/mock (but with a different behaviors ⚠️) and it respects the plug-and-play aspect of it: default mocks just work.

I've set it up on a (private) project and it works pretty well. Compared to @graphql-tools/mock, there are still some missing features (see Todos section of README) but they can be implemented apriori easily.

I'm not sure that, in the future, I'll have the necessary work bandwidth to maintain the library. So, if there is a way that the idea could be part of graphql-tools, I'd be happy to work on it. Just let me know how maintainers would see that. cc @ardatan

@ardatan
Copy link
Owner

ardatan commented Jul 27, 2020

@alexstrat We'd love to have it under graphql-tools! Feel free to open a PR!

@alexstrat alexstrat mentioned this issue Nov 17, 2020
9 tasks
@ardatan
Copy link
Owner

ardatan commented Feb 18, 2021

We have it now!
https://www.graphql-tools.com/docs/mocking

@ardatan ardatan closed this as completed Feb 18, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New addition or enhancement to existing solutions
Projects
None yet
Development

No branches or pull requests

2 participants