Before we start
This lesson is a continuation of the problem spotted in Using MSW library to remove implementation details from tests article.
In Creating testing fixtures article you can read more about this concept.
In the previous lesson, we added MSW library to our setup and we refactored our integration tests. At the end of the lesson, we came to the conclusion: "Holly cow, so much boilerplate is produced in every test suite...". Just look at the following example:
We can improve it with a simple fixture pattern. We need a function that allows us to mock any endpoint in an easy way.
Let's design a "serverFixture" API
Let's first check what we have now.
Our new API should be simple, should reduce the boilerplate, and should be flexible.
We'll have less code - that's obvious and we don't need to remember using all of these reset and setup functions in before and after callbacks - forgetting them may cause unexpected issues and they are hard to spot for not experienced developers.
Also, we removed the need to use server.use wrap, which may be also forgotten.
Implementing the "serverFixture" function
The first thing that may be weird is the following code:
Why do we need to pass beforeAll, afterEach and afterAll callbacks?
It's because, in the testing environment, our fixture function will not have access to jest environment. So, we need to pass these functions as a parameter and call them inside our util. Check the GIF to understand:
Jest functions can be accessed only in test.ts files
Why it's like that? It's because if you use these functions in your regular code you'll add them to the bundle...
This is the perfect use case for dependency injection pattern and currying technique. Instead of using globally available functions from jest, we'll pass them inside to fixture via parameter.
If you're interested about patterns, feel free to check the Closures, currying and functions composition as your new friends article.
Let's add the required boilerplate and prepare some types.
Now, we need to create a file with types.
Okay, now the code is working. We need to add the last part - the mock function that will truly add mocks to the dedicated endpoint. The mock function will have the following signature.
The last part - we need to align the implementation!
Using the "serverFixture" in tests.
We have serverFixture fully implemented. Now, we need to use it.
Gotchas and additional stuff
What if you would like to do something more via after and before functions?
You don't need to worry about that. The jest will call beforeAll twice. In your testing code and internally inside the serverFixture function!
The final walkthrough
Check the GIF below to understand how it works in practice and how blazingly fast you can now mock your endpoints in integration test without remembering additional stuff.
How it works?
In the following repository you can dive into examples that we discussed and many more! Here you have the final code:
Conclusions and thoughts
We reduced the amount of boilerplate, and things to remember and we added reusable fixture for mocking server endpoints. Writting integration tests right now it's not a guilty pleasure anymore...
- 1. Basics
Grouping the tests
The usage of describe and it
The best practices for naming tests
Types of tests
- 2. Mastering unit testing
Project and tests setup
Unit tests review
React component testing
Snapshot testing in React
Understanding stubs in testing
Understanding mocks in testing
Creating testing fixtures
Using spies in React and Typescript
Mocking environment variables
- 3. Mastering integration testing