Mocking
Mocking
WunderGraph testing library comes with builtin support for mocking your HTTP datasources or APIs. This allows you to test your application without having to rely on external services.
Our testing library is framework agnostic, so you can use it with your preferred test framework. We use Vitest in this guide. It is a Jest Compatible test runner, but it should be easily adaptable to any testing framework.
Initial setup
Make sure your wundergraph.config.ts
is set up to generate the WunderGraph testing library. Take a closer look at the url
. We use an environment variable to set the URL of the datasource. This allows us to replace the URL with the mock server URL when running the tests.
Test setup
Within a test, you can import createTestAndMockServer()
to create the test and mock server instances. Note that depending on your project's settings, the path might be slightly different depending on where you generate your templates. We use beforeAll
to start the test and mock server instances. The ts.start()
method returns a cleanup function to shutdown all servers. Alternatively, you can call ts.stop()
. In vitest you can return an async function to do a cleanup. We also use mockURLEnvs
to replace the environment variables with the mock server URL.
Before you run the tests and import the createTestServer
function, you must run wundergraph generate --env .env.local
to generate the testing library. Some testing frameworks like Vitest or Jest provides a globalSetup
hook that allows you to run a script before running the tests. In that way, you can automate it.
Environment variables
WunderGraph has builtin support for loading environment variables from a .env
file. For testing, we recommend creating a .env.test
file to set the environment variables for the test environment. This allows you to set the environment variables for the test environment without affecting your local development environment. The test server search first for a .env.test
file, and if it doesn't exist, it will fall back to .env
. You can also pass environment variables to the test server with the env
option of the createTestAndMockServer
method. None of these files should be committed to git. In your CI, you should use plain environment variables that come from your secret store.
Writing tests
We recommended creating as few testing server instances as possible. These minimizes the number of times the server starts and stops, making your tests faster.
Due to the nature of the mock server, it is not possible right now to run multiple tests it
concurrently. If you have a demanding test suite, you can create multiple test files and vitest will run them in parallel by default.
Mocking HTTP datasources
When you setup a mock with mock()
and the request matches, the mock server will return the response. If the request does not match, the mock server will return a 404 response and the call to scope.done()
will fail the test. You have also the ability to throw an error inside the response function to fail the mock. This is useful if you want to verify with test assertion that the request is correct. A thrown error is handled as an unmatched request and the next mock will be checked.
The first argument of the mock
function is an object that accepts the following properties:
match
- A function that returns true if the request matcheshandler
- A function that returns the response or throws an errortimes
- The number of times the mock should be called. Defaults to 1.persist
- If true, the mock will not be removed after any number of calls. Be careful with this option, as it can lead to unexpected results if you forget to remove the mock withts.mockServer.reset()
after the test. Defaults to false.
Make a request and validate the mock
The createTestAndMockServer
returns a WunderGraphTestServer
object that wraps the test server and the auto-generated type-safe client.
If an assertion fails or any error is thrown inside the handlers, the test will fail and the error will be rethrown when calling scope.done()
. This ensure that the test runner can handle the error correctly e.g. by printing a stack trace or showing a diff.
For a full example please check the example in the WunderGraph repository
Summary
This guide showed how easy it is to mock HTTP datasources. It gives you power to write integration tests fast and reliable. You can apply the same principles to mock any HTTP API in your TypeScript functions.