lipanski / mockito

HTTP mocking for Rust!
MIT License
686 stars 59 forks source link

graphql mocks #81

Closed matteosister closed 5 years ago

matteosister commented 5 years ago

Hi! First of all: thanks for this library!

We use mainly graphql endpoints, and the semantics of exposing a graphql server via http is pretty standard. A POST request with json body, with query (string) and variables (json) keys.

Matching on graphql queries is really not trivial, and I'm experimenting with a library that uses graphql_parser to match on the request and responds with the right body. The tricky part is that graphql could be used to perform multiple queries at once, so it's not as trivial as a regex matcher.

What do you think about adding this funcionality to mockito? Would this be out of scope? Would you accept a PR?

Thanks again for the awesome work, I learned a lot by reading your code :+1:

lipanski commented 5 years ago

hi Matteo

thanks a lot for the appreciation!

thinking out of my head I'd say a GraphQL matcher would be a bit too specific for this crate.

but based on the Json and JsonString matchers I could imagine introducing something like a PartialJson and a PartialJsonString matcher, that can be applied partially but with the same (Json) syntax.

would that work for you? could you think of something else that abstracts out GraphQL from this problem? some examples of what we're dealing with would also be appreciated.

matteosister commented 5 years ago

for simple queries we already do something with Json and JsonString. And it's somewhat ok, not too easy or enjoyable though.

A graphql http layer is something like:

{
  "query": "...",
  "variables": {"a": 1, "b": "b"}
}

where the query could be (as a string):

query($a: Int!, $b: String!) {
  test(for: $a) {
    field1
    field2
  }
  anotherTest(val: $b) {
    field3
  }
}

right now, we are matching on the variables part, which is a simple json. It would be great to have a generic matcher for http graphql endpoint. The api could be something like:

let _m = mock("POST", "/graphql")
      .match_graphql_query("test")
      .match_graphql_mutation("aMutation") // graphql has queries and mutations
      .match_graphql_parameter(Int("a", 1))
      .with_body("{'data': {'test': {'field1': 1, 'field2': 2}}}")
      .create();

What do you think?

Another problem we are facing, while trying to use json body matcher, is that the match is all or nothing. As far as I know it's not possible to partially match a json structure, is it true? Maybe this could be implemented in mockito?

lipanski commented 5 years ago

as mentioned in my previous comment, I'd avoid implementing anything GraphQL specific atm in Mockito but I'd be open to introducing the following matchers:

...which should help you out in your task. PRs are welcome :)

matteosister commented 5 years ago

as mentioned in my previous comment, I'd avoid implementing anything GraphQL specific atm in Mockito but I'd be open to introducing the following matchers:

  • Matcher::PartialJson(serde_json::Value)
  • Matcher::PartialJsonString(String)

...which should help you out in your task. PRs are welcome :)

@lipanski https://github.com/lipanski/mockito/pull/82

lipanski commented 5 years ago

82 was released in 0.20.0