DEV Community

Cover image for Integration vs Unit Testing: How to Choose
George Linardis
George Linardis

Posted on • Updated on • Originally published at codingoctopus.com

Integration vs Unit Testing: How to Choose

If you are taking the first steps in testing your code, first of all, let me congratulate you for walking that path! 🥳 This is a very important decision and a great addition to your skill set.

Before you continue writing some tests though, you should understand the difference between two of the most important testing types, integration, and unit tests. So let’s immediately dive in, to take a glimpse at their differences.

Testing scenario

To understand the difference between integration and unit testing let’s use an example of a function that calculates a user’s daily budget. Our function will be named determineUserBudget and have the following characteristics:

  • Get a userId parameter for searching for a user

  • It will use the userId to search for the user in our database’s Users table.

  • If the function is called and no userId is passed it will throw an Error.

  • If no user is found it will throw an Error.

  • If a user is found it will use the user’s info, call our Budget service and calculate the budget.

  • Finally, it will return the budget.

Let’s see that in a simplistic diagram:

Diagram showing stucture described

Now that we have our testing scenario, let’s see what’s the difference between these two types of testing and how we’d test our function in each case. (We won’t be writing any code in this post).

Unit testing

When writing a unit test we want to isolate the part of the code we are testing from the rest of the system. This is the main characteristic of unit tests, isolation!

Think about it as focusing all your energy only on what’s happening inside a function and not on the function’s calls/interactions with the database or any other functions called.

In our scenario, to test determineUserBudget, we’d ignore the call to our database and the call to the budget service. The only thing that would need to be covered by tests, would be, checking if all potential function flows (see green arrows) are followed depending on the function’s usage.

Previous structure but isolated

But what about the two calls in the database and service? When writing unit tests, these calls are replaced by mock functions.

🕵 Mock function is a function that replaces the behavior of an actual function during the testing

To effectively create a mock function, it is necessary to have knowledge of the response type and structure returned by the function being mocked. With this understanding, it is possible to simulate the response by replacing the actual function with a mock function during testing.

After replacing the external calls with mocked ones we can safely focus on testing the function without interacting with the external environment, in isolation that is.

Integration testing

In contrast with unit tests, the keyword on integration tests is not isolation but interaction. Through integration tests, we are testing how our different parts of code interact with each other.

In our testing scenario, we’d test everything! We would test the potential flows of our function including the interaction with the database and the service. The difference with the unit test is that we would pass real data and receive back real data to test.

It’s important to note that when I mention using real data, I am not referring to the same data used on the live site. Using production data in testing can lead to serious issues. Instead, by real data, I mean that the test will interact with data that is relevant to the testing environment. For example, when testing locally, the test would use data from the local database, and when testing on a staging environment, the test would use data from the staging database.

🕵 Staging environment is an environment used for testing features and bugfixes before deploying them on production. A safe simulation of a site or software used in production.

Reminder
Do not include in your testing scope, testing external package dependencies. These should be considered as tested by the package provider.

Which one to choose?

Well although this question never has only one answer, if it had only one answer it would be it depends. And yes I know you probably don’t like that answer. In that case, meaning if I had to choose one answer, I would say that you probably need to always choose both types. Unit tests are awesome for checking function flows but integration tests are the best if you want to sleep at night! What I usually do is, write at least one integration test for a complex function and many unit tests for any function called by the complex one.

Till next time. 🤓

Top comments (0)

12 APIs That You Will Love

Free and easy to use APIs for your next project, learning a new technology, or building a new feature.