Khan / Khan/genqlient

Support for tests/mocking in genqlient

Open
#108 6 comments 1 reaction 0 assignees View on GitHub
enhancement
Dominant language
Go
Stars
1.3k
Forks
143
Avg merge
4h 50m
Merged PRs (30d)
1

Description

My thought here is that for every function `Myquery` that genqlient produces code for, it also produces a function `MockMyquery`, that can be used in tests. But we do away with strong typing altogether!, and use the js.Obj system from Khan Academy. The justification for this is that, unlike for prod code, it's ok to do type-checking at runtime for tests. And specifying js.Obj{} objects is just much nicer to write than all the super-long type-names that would be provided if we specified Go types.

Specifically, my thought is the API might be:
MockMyquery(ctx context.Context, testClient graphql.Client, varsToMatch js.Obj, output js.Obj)
and this would add a mux to testClient so whenever you queried that client on Myquery with args that match `varsToMatch`, the client would return `output`. (Alternately, we could have you pass in a mux yourself, and you could attach it to your test-client however you want; that matches the httplib model better and may be easier or harder to use, I'm not sure.)

The logic of MockMyquery() would include code to validate the schema: to make sure that varsToMatch includes all required vars and they can all be coerced to the proper type, and likewise that the output matches the query's schema.

varsToMatch could include all the js matchers that we have at Khan, such as `js.UnorderedArray{}`. It could also include a new `js.Any` to match anything. (Because leaving a required var out of varsToMatch would be an error, rather than the existing Khan Academy logic where it's an implicit js.Any.) You could just pass in `js.Any` directly for `varsToMatch` to mean "return the given output for all Myquery queries."

I am thinking the codegen would also just create the test helper files to a package generated/genqlient/js/. So clients could import that and use js.Obj/etc like they do at Khan Academy already.

[genqlient.tar.gz](https://github.com/Khan/genqlient/files/7212703/genqlient.tar.gz) holds the relevant files we use at Khan Academy:
* The files that would go in the genqlient/js/ dir (in the js/ dir in the tarball)
* mux.go (in case it's helpful)
* query_validation.go, response_validation.go (how we validate against the schema)
* testing.go (to create a mock client)

Contributor guide

Open the contributing guide

Research direction

Start by examining the attached genqlient.tar.gz, especially js/, mux.go, query_validation.go, response_validation.go, and testing.go, then compare those pieces with the repository's code-generation entry points. Resolve the proposed mock-client API, matcher behavior, validation rules, and generated package location before implementation. Done means the design is settled and covered by tests for variable matching and response validation.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, graphql
Domain
api, testing
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.