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?
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.
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.
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
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.
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.
We've practised mocking environment variables and reuse of logic in tests using fixtures. It is worth mentioning that environment variables are not the only global objects that we fix in this way. We will discuss this in the next lessons.
If you enjoyed it, be sure to visit us on Linkedin where we regularly upload content from programming.
- 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