Hi, I am Nicolas

Full Stack Software Engineer who cares deeply about UI and UX. Passionated to build magnificent products people love to use. Currently at PSPDFKit building industry leading frameworks with React & Elixir.

Test your GraphQL API in Elixir

Sep 3, 2017

I recently started developing a new Phoenix application that uses GraphQL. We decided to use the Absinthe GraphQL Library and it was the right decision so far. The maintainers are super nice and actively help with problems in the Elixir Slack channel. If you haven’t used GraphQL and want to learn about it, I can recommend you to go through How to GraphQL and I promise you, you will never want to go back and build a REST API again!

How a GraphQL Query looks like

GraphQL APIs work by sending a POST HTTP requests to the GraphQL endpoint (e.g. /api/graphql) with a query and a variables as parameter. As a response, you get an HTTP Success Status with a data or an error JSON Object. This, of course, is abstracted away by the GraphQL client libraries like Apollo or Relay. However, when you want to test your API, it becomes important to know how you form such a request. Normally, when testing APIs, you have controllers that are bounded to certain routes, with GraphQL you only have one single endpoint - so I asked myself what’s the best approach to test this?

Building GraphQL Queries

We assume, to have the following GraphQL User Type:

1
2
3
4
5

# Type definition of a UsertypeUser{id:ID!name:String!}

And our queries and mutations are the following:

1
2
3
4
5
6
7
8
9

# Query to get all userstypeQuery{users:[User!]!}# Mutation to update a user's nametypeMutation{updateUserName(id:ID!,name:String!):User!}

As we already know, the HTTP request of a GraphQL query is relatively easy to build. For our users query, we don’t need any variables, so we can just add a query attribute to our payload.

However, repeating this every time would be annoying and I wanted to have a much nicer API.

Create a GraphQL test helper

Because most of the time I just want to create a GraphQL query and immediately send it, my idea for the API looked like this:

1

build_conn()|>graphql_query(query:@query)# => Returns result

So I built a GraphQLHelper to do so:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# test/support/graphql_helper.exdefmoduleMyApp.GraphqlHelperdousePhoenix.ConnTest# We need to set the default endpoint for ConnTest@endpointMyApp.Web.Endpointdefgraphql_query(conn,options)doconn|>post("/api/graphql",build_query(options[:query],options[:variables]))|>json_response(200)enddefpbuild_query(query,variables)do%{"query"=>query,"variables"=>variables}endend

To make this helper accessible per default in your tests you need to import it in ConnCase.

Authentication

The request alone wouldn’t work, we also need to add authentication. Because we use a token-based authentication in our API I also added a small AuthenticationHelper that creates a new user session and adds the token to the HTTP Header.