If you want to use the server starter directly without going through the tutorial, find the code on Github. Link to the next parts are at the bottom of this page.
Requirements: Knowing why testing is important (😉).
☕ Mocha Setup
Let’s add the following packages:
npm i -D mocha chai @types/mocha @types/chai apollo-server-testing mongodb-memory-server
- We will use apollo-server-testing to mock a GraphQL client.
- To mock the database without using/conflicting with the development one, we will use mongodb-memory-server. It will create a temporary MongoDB database in the RAM for our tests.
Let’s add the test command to our scripts in the package.json file:
"test": "mocha --require ts-node/register test/**/*.ts"
We also want to exclude the test folder from the docker copy and typescript compilation. This means adding
test to the excluded folders section of
tsconfig.json and to the list in
Writing the tests
Mongo-memory-server is super useful to quickly set up a temporary database that will only live in the host’s RAM during the tests. Create a
test/TestDatabaseManager.ts file and copy/paste the following code:
Similarly to the AppDatabaseManager we already wrote for our actual server, the TestDatabaseManager inherits from ADatabaseManager. Instead of using MongoDB’s NodeJS driver to connect to a real database, we’re using MongoMemoryServer to generate a temporary database (named “test”) and a connection string (uri).
Regarding the actual tests, we’d like to connect to the test database before running them, as well as disconnect when they are done. We’d also like to clean the database between each test. To solve this, Mocha is providing “hooks” that will allow us to run some code before and after all the tests, and even in between.
The ideal architecture would be to split tests into multiple files and still be able to benefit from the hooks and access the common variables in each one of the files:
Let’s create a file (corresponding to the red one above) called
test/all_db.test.ts and add the following code:
- Mocha is using “describe(name, suite)” to create a suite of tests. The “all” suite is encapsulating all the other suites (the “user” one at line 30, and we can add as many as we want using the
before, we are instantiating
dbManagerbecause we will need it to access the database in the tests.
- We are creating a test client, provided by apollo-server-testing (and relying on the TestDatabaseManager). We will use this test client to test our GraphQL API.
after, we are properly cleaning the resources we used.
beforeEach, we are cleaning the database. It ensures there’s no data left from the previous test when executing the tests one by one.
It is simply a data class, holding the variables we need for our tests.
The last file we need to add is the actual user test file (
test/user.test.ts), containing 2 tests:
- From line 8 to 36, we are testing the
addUserendpoint. First by testing the GraphQL mutation, and what it is returning (by comparing
user). Then, by checking that an entry was created in the database (comparing
- From line 38 to 64, we are testing the
- If you need more info about how the testClient is working, check Apollo’s official documentation. Basically we are using the
createTestClient()is returning us, to mock a GraphQL client.
Now we can run
npm run test and see our tests running 😎.
That’s it! We covered many topics in these articles, and we now have a generic foundation that can easily be extended to meet any need. 🥳
We won’t cover the deployment since there are already a ton of resources available out there. It should be pretty straightforward because our whole back-end is containerized. Let me know if you would like to know more about it.
Thank you for making it to the end. I hope you learned something along the way, and I would love to hear your input and feedback if some things could be done better using other techniques. Big thanks to the authors of these articles too, they were very valuable resources to build this tutorial and I recommend them to everyone:
- How to set up a powerful API with GraphQL, Koa and MongoDB, by Indrek Lasn.
- Smooth Local Development with Docker-Compose, Seeding, Stubs and Faker, by Philip Hauer.
- This StackOverflow answer about nesting the Mocha tests, by Louis.