Test gqlgen resolvers that rely on context values
The problem
You are using gqlgen for building GraphQL servers in your Go projects. But your queryResolver
or mutationResolver
rely on some context value. For example as you are using gin and add values to your request context with middlewares. Therefore you need a way to modify the context of the gqlgen client in your tests.
An example resolver code could look like the following.
1func (r *mutationResolver) CreateCategory(ctx context.Context, title string) (*model.Category, error) {
2 currentUser := ctx.Value("User").(db.User)
3
4 // ...
5
6 return result, nil
7}
The solution
The following code shows you how to add values to context when testing gqlgen resolvers with the client.
1// Add param variables to context of client request
2// The gqlgen client accepts functional options as the following one
3func addContext(user db.User) client.Option {
4 return func(bd *client.Request) {
5 ctx = context.WithValue(ctx, "User", user)
6 bd.HTTP = bd.HTTP.WithContext(ctx)
7 }
8}
9
10// Example tests
11func TestMutationResolver(t *testing.T) {
12 // Create the gqlgen client for testing
13 h := handler.NewDefaultServer(generated.NewExecutableSchema(generated.Config{Resolvers: &Resolver{}}))
14 c := client.New(h)
15
16 // Example test
17 t.Run("Create category", func(t *testing.T) {
18 // struct that saves the response of the mutation below
19 var resp struct {
20 CreateCategory struct{ Title string }
21 }
22
23 // Create the variable that is passed to addContext
24 user := db.User{}
25
26 // Call the resolver via the client and modify the context via functional options
27 c.MustPost(`
28 mutation($title: String!) {
29 createCategory(title:$title) {
30 title
31 }
32 }`,
33 &resp,
34 client.Var("title", category.Title),
35 addContext(user),
36 )
37
38 // an example assertion
39 assert.Equal(t, "Awesome blogs", resp.CreateCategory.Title)
40 })
41}