How to Write Integration Tests for MongoDB Atlas Functions
Rate this tutorial
As of June 2022, the functionality previously known as MongoDB Realm is now named . Atlas App Services refers to the cloud services that simplify building applications with Atlas – Atlas Data API, Atlas GraphQL API, Atlas Triggers, and Atlas Device Sync. will continue to be used to refer to the client-side database and SDKs. Some of the naming or references in this article may be outdated.
Integration tests are vital for apps built with a serverless architecture. Unfortunately, figuring out how to build integration tests for serverless apps can be challenging.
Today, I'll walk you through how to write integration tests for apps built with MongoDB Atlas Functions.
This is the second post in the DevOps + MongoDB Atlas Functions = 😍 blog series. Throughout this series, I'm explaining how I built automated tests and a CI/CD pipeline for the . , I explained and . Then I walked through . If you haven't read the first post, I recommend starting there to understand what is being tested and then returning to this post.
Integration tests are designed to test the integration of two or more components that work together as part of the application. A component could be a piece of the code base. A component could also exist outside of the code base. For example, an integration test could check that a function correctly saves information in a database. An integration test could also test that a function is correctly interacting with an external API.
When following the traditional test pyramid, a developer will write significantly more unit tests than integration tests. When testing a serverless app, developers tend to write nearly as many (or sometimes more!) integration tests as unit tests. Why?
Serverless apps rely on integrations. Serverless functions tend to be small pieces of code that interact with other services. Testing these interactions is vital to ensure the application is functioning as expected.
Let's focus on one test case: storing the statistics about a single Tweet.
- Calls the
removeBreakingCharactersfunction to remove breaking characters like emoji.
- Converts the Tweets in the CSV to JSON documents.
- Loops through the JSON documents to clean and store each one in the database.
- Returns an object that contains a list of Tweets that were inserted, updated, or unable to be inserted or updated.
We won't use any mocks in the integration tests. Instead, we'll let the
storeCsvInDbfunction call the
removeBreakingCharactersfunction and the database.
Next, I imported several constants from
constants.js. I created the
constants.jsfile to store constants I found myself using in several test files.
Next, I imported the
realm-webSDK. I'll be able to use this module to call the Atlas Functions.
Then I created some variables that I'll set later.
Now that I had all of my prep work completed, I was ready to start setting up my test structure. I began by implementing the function. Jest runs
beforeAll()once before any of the tests in the file are run. Inside of
beforeAll()I connected to a copy of the App Services app I'm using for testing. I also connected to the test database hosted on Atlas that is associated with that App Services app. Note that this database is NOT my production database. (We'll explore how I created Atlas App Services apps for development, staging, and production later in this series.)
I chose to use the same app with the same database for all of my tests. As a result, these tests cannot be run in parallel as they could interfere with each other.
My app is architected in a way that it cannot be spun up completely using APIs and command line interfaces. Manual intervention is required to get the app configured correctly. If your app is architected in a way that you can completely generate your app using APIs and/or command line interfaces, you could choose to spin up a copy of your app with a new database for every test case or test file. This would allow you to run your test cases or test files in parallel.
Now that my test infrastructure was complete, I was ready to start writing a test case that focuses on storing a single valid Tweet.
The test begins by calling the
storeCsvInDbAtlas Function just as application code would. The test simulates the contents of a Twitter statistics CSV file by concatenating a valid header, a new line character, and the statistics for a Tweet with standard characters.
The test then asserts that the function returns an object that indicates the Tweet statistics were successfully saved.
Finally, the test checks the database directly to ensure the Tweet statistics were stored correctly.
After I finished this integration test, I wrote similar tests for Tweets that contain emoji as well as for updating statistics for Tweets already stored in the database.
Integration tests are especially important for apps built with a serverless architecture. The tests ensure that the various components that make up the app are working together as expected.
Be on the lookout for the next post in this series where I'll walk you through how to write end-to-end tests (sometimes referred to as UI tests) for serverless apps.
Check out the following resources for more information: