GraphQL — Testing our Object Type definitions with Jest

How to use Jest in order to implement Integrity tests on our Object Type definitions.

How many tests should be in a test suite? Unfortunately, the metric many programmers use is “That seems like enough.” A test suite should test everything that could possibly break. The tests are insufficient so long as there are conditions that have not been explored by the tests or calculations that have not been validated.
(Clean Code, Robert C. Martin)

Based on that premise, when we are creating a new GraphQ LAPI, in order to ensure that the models defined by the API don’t change, which could give rise to possible problems on our backend code, it’s important to keep tracking these definitions with the proper Integrity tests.

Yes, I’ve said Integrity tests and not integration ones. This is that because with this kind of tests, we are going to check that the definition of the tested Object Types remains constant along the application development lifecycle.


Base Code

In order to expose how to implement the tests for a GraphQL API, I would like to highlight two starting points:

  1. I’m going to base all this example code on the Javascript language.
  2. I’m going to use the Jest testing framework.

After that, the basic configuration of my project is next:

In addition, the structure of the project that I’m going to use for this paper is next:

The whole code shown on the next steps is accessible on this GitHub repository.


Taking a look to the code that we are going to test

As you can guess by the project structure shown on the previous section, I’m defining the model for a user which will be composed by different kind of filed types such as Strings, Booleans, Emails, Addresses, etc.

This is the code of our user.type.js file.

As we can see in the previous code, we are importing three additional and custom Object Types ( PhoneNumberType, EmailAddressType and TimestampType) that are going to be used in order to define the type of a few fields in our user definition.

This way, the content of phone.number.type.js is next:

On this script, I’ve defined a GraphQLObjectType and a GraphQLInputObjectType. That is so because, the first one will be used when we run queries meanwhile the second object will be used when we receive input data on mutations.

Finally, the content of the email.address.type.js is that:

On this case, we are getting the same situation than in the phone.number.type.js file, I mean, we will use the first ObjectType for queries and the InputType for mutations.


Testing time

After we have reviewed the code base that we are going to test, it’s time to start run our testing tool. To do that, we have to open a terminal and (being into the project folder) run the next command:

npm test

Due to we have not defined any test yet, we will receive the next result:

Ok, now we are going to begin creating the testing files, so we are going to do that with one of the simplest Object Type definitions, it means, the phone.number.type.js one.

To do that, we have to create a new file named phone.number.type.test.js and populate it with the next code:

We start importing the Jest and GraphQL modules in one hand and, in the other one, we also import the Object Type that we want to test.

After that, we have defined a describe block were we have typed two different tests. The first one is focused on test the object used for queries meanwhile the second test section is defined for the object used for mutations.

In both cases, we take advantage of the method getFields() provided by the Object Type (PhoneNumberType on this case).

Once we have stored all the Object Type fields into the phoneNumberFields variable, we are able to check them.

In order to do that, I’m going to use two matchers provided by Jest.

With the first one (toHaveProperty) we are checking that the Object Type contains a specific field.

The second matcher (toMatchObject) will allow us to check if the type of the field is the specific one that we have defined in the model.

Finally, we save the file and then, we have to take a look to the terminal where we run the testing environment. We should have obtained a result similar to that:

Great!!! Our tests are done and all in green.

Ok, let’s go with tests for the email.address.type.js file.

In order to do that, we are going to repeat the same steps, so firstly, we create the file email.address.type.test.js and then, we populate it with the next code:

As we can see, on this new script we have implemented the same procedures that for the phone.number.type.js file but on this time, we have been working with the EmailAddressType object.

Now, we save the file and check the terminal again. We should have obtained a result similar to that:


Testing fields with nested Object Types

Until now, we have implemented tests in order to verify fields which are defined as specific GraphQL data-types but, what happend with Object Types which fields type definition are another Object Type? How can we test them?

In order to do that, we are going to base on the UserType object definition where the phoneNumber, emailAddress, lastLoginTimestamp, createdAt and updatedAt fields are typed as another Object Type (PhoneNumberType, EmailAddressType and TimestampType).

To test this object, we are going to create a new file named user.type.test.js and populate it with the next code:

As we can see, we have no problems in order to test imported/nested Object Types.

After that, if we save the file content and check the terminal where we have run the testing tool again, we will be able to see a result similtar to that:

Nice. All our tests are in green.


Checking that tests are really working success

In order to verify that our tests environment is working as we will, we are going to edit the user.type.js content and replace the username field type definition form GrpahQLString to GrpahQLInt.

After that, we save the file and check the terminal a last time. We should have obtained a result like that:

That is it. Our test has failed because the data-type matching is not correct.


Conclusion

With this last example we conclude that the integrity testing is possible in GraphQL and they can be included in our testing stack.

This way, if along the API development, some of the defined types is modified in any of the multiple created Object Types, our tests will warn us.

I hope this paper has been useful for you. If it’s so, please, clap it and share on your social networks.

If you want, you can find me on Twitter and Linkedin.

Thank you and regards.