Intro
How we can mock environment variables, and when we should do this? Let's build a small test fixture to mock any env variable.
Prelude
Sometimes we want to test code that internally uses environment variables. If we do not mock them, our tests may behave in an unpredictable way, which we do not want.
Imagine that you run code that relies on an environment variable and you forget to have it set in the .env file. What will happen?
BOOM 💥
Just kidding. Simply said, the tests will not pass. What can be done to make the tests we run always independent from the environment in which they are executed?
That's right. We need to mock the global object that our code refers to.
Let's start with an example
Please look at the following code snippet, in which we try to get a URL to our API with the getUrl function.
Loading
At the very beginning, we declared the shape of the global object process.env only for the file with our code - outside of it, this object will have a default typing. Thanks to this, we limited other possibilities of using our variable. The function we created is supposed to be the only possible way of accessing the URL.
This is how we will get this URL in various files.
Loading
As a curiosity, it is worth adding that the used approach, in which we throw an exception in the absence of a variable is called fail fast. Code without an environment variable won't work anyway, so we throw an exception that immediately points to a potential cause of the problem.
Let's mock the environment variable!
Okay, let's write a test to check:
- Exception throw if there is no variable
- Variable return if exists
Loading
We need to make sure that after modifying the global process object, we set the value again to the initial one. Otherwise, we may influence other tests. This is standard practice when operating on global objects in tests. This also applies to value removal.
So what, so that's the end of it?
Exactly right. That's all that was needed to mock the object value of the environment variable. Let's add a few more minor improvements before we finish this lesson.
Small testing improvements
Since we know that we need to set and reset the value of our global variable - we can use something we've already seen in this course. Indeed! Fixtures!
You can check how fixtures work in this lesson.
So let's create a simple environmentFixture function, that will make our tests much prettier.
Loading
We encapsulated the repeatable logic in the fixture function. Besides, we can use this logic in other tests - simply by creating a separate file, and importing it where it's needed.
If you are interested in the created util, I also recommend the entry: Mocking up with factories.
Summary
We've practiced mocking environment variables and reuse of logic in tests by using fixtures. There is still a place for improvement - the dependency injection pattern may be used to remove the need of manually using fixture.restore(). It's described in the next lesson - ⭐ Using dependency injection pattern to improve fixtures.
- 1. Basics
10 minutes
Software testing
2 m
Grouping the tests
1 minute
The usage of describe and it
2 m
The best practices for naming tests
2 m
Navigating the different types of software tests
3 m
- 2. Mastering unit testing
38 minutes
Project and tests setup
3 m
Unit tests review
4 m
React component testing
5 m
Snapshot testing in React
4 m
Understanding stubs in testing
3 m
Understanding mocks in testing
5 m
Creating testing fixtures
4 m
Using spies in React and Typescript
3 m
Mocking environment variables
3 m
Using dependency injection pattern to improve fixtures
4 m
- 3. Mastering integration testing
12 minutes
Understanding the integration tests
4 m
Using MSW library to remove implementation details from tests
4 m
Creating fixture for MSW to reduce boilerplate and setup
4 m
- 4. Mastering e2e tests
8 minutes
Comments
Add your honest opinion about this article and help us improve the content.