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.
In order to expose how to implement the tests for a GraphQL API, I would like to highlight two starting points:
- 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
As we can see in the previous code, we are importing three additional and custom Object Types (
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.
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:
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
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
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
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
updatedAt fields are typed as another Object Type (
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
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.
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.
The latest Tweets from Dailos R. DÍAZ LARA (@dDiaLar). Cross-platform Software Developertwitter.com
View Dailos Rafael DIAZ LARA’S professional profile on LinkedIn. LinkedIn is the world’s largest business network…www.linkedin.com
Thank you and regards.