---
title: Unit Testing JSONata Expressions in Notehub with JavaScript and Jest
description: Using the popular JavaScript testing framework, Jest, you can test your JSONata expressions and Events from Notehub.
source_url: https://dev.blues.io/blog/testing-jsonata-notehub-jest-javascript/
canonical_url: https://dev.blues.io/blog/testing-jsonata-notehub-jest-javascript/
markdown_url: https://dev.blues.io/blog/testing-jsonata-notehub-jest-javascript.md
---

# Unit Testing JSONata Expressions in Notehub with JavaScript and Jest

![Unit Testing JSONata Expressions in Notehub with JavaScript and Jest banner](https://dev.blues.io/images/blog/posts/testing-jsonata-notehub-jest-javascript/banner.png?v=7bc7251f)

January 8, 2025

## Using the popular JavaScript testing framework, Jest, you can test your JSONata expressions and Events from Notehub.

- [Notehub](https://dev.blues.io/blog/tag/notehub)
- [JSONata](https://dev.blues.io/blog/tag/jsonata)
- [Testing](https://dev.blues.io/blog/tag/testing)

[![Rob Lauer](https://dev.blues.io/images/blog/authors/rob-lauer.jpg?v=57fb21a7)](https://dev.blues.io/blog/author/rob-lauer/)

[Rob LauerSenior Director of Developer Relations](https://dev.blues.io/blog/author/rob-lauer/)

Testing. Nobody *actually* wants to do it. The act of writing tests is tedious, time-consuming, and rarely provides value. Right?

Except of course when you deploy to production on a Friday afternoon, expose a regression that nobody ever thought could possibly happen, and then spend your weekend picking up the pieces! (Not speaking from experience of course...)

[Unit testing](https://en.wikipedia.org/wiki/Unit_testing) has become an essential practice for ensuring code quality and robustness, especially in environments where multiple contributors may be editing the same codebase.

This article will help guide you through the process of **unit testing JSONata expressions with Jest and VS Code**, and even how to test expressions and Events directly from your Notehub project.

### A Brief Intro to JSONata and Jest

[JSONata](https://jsonata.org/) is a query and transformation language for JSON, allowing developers to extract, manipulate, and transform JSON data. It is particularly useful in scenarios like tranforming data sent to a [Notehub Route](https://dev.blues.io/notehub/notehub-walkthrough.md#routing-data-with-notehub) (e.g. transforming JSON to reduce the size of the payload, conforming to a remote endpoint's requirements, and/or performing dynamic calculations) before it is then delivered to a cloud application.

JSONata offers powerful capabilities for handling JSON data, but like anything else, its expressions and functions should be tested thoroughly.

> **Note:**
>
> You can read more about writing JSONata expressions in our guide on [Using JSONata to Transform JSON](https://dev.blues.io/guides-and-tutorials/notecard-guides/using-jsonata-to-transform-json-in-notehub.md).

[Jest](https://jestjs.io/) is a popular testing framework for JavaScript that provides a rich API for writing unit, integration, and end-to-end tests. It is highly favored in the JavaScript community for its simplicity, speed, and mocking capabilities.

Combining JSONata with Jest allows us to write automated tests to ensure that our JSON data manipulations and transformations work correctly.

Let's look at how we can build some tests of our own with Jest and VS Code.

## Setting Up Our Environment

Before we begin writing tests, we need to set up our dev environment:

### Installing Node.js and npm

First, ensure that you have Node.js and npm (Node Package Manager) installed. You can download the installer from the [official Node.js website](https://nodejs.org/).

To check if you already have Node.js and npm installed, run the following commands in your terminal:

```bash
node -v
npm -v
```

If both commands return a version number, you are good to go!

#### Setting Up a New Project

Navigate to an arbitrary directory and initialize a new Node.js project:

```bash
mkdir jsonata-jest-testing
cd jsonata-jest-testing
npm init -y
```

Next, install Jest as a development dependency:

```bash
npm install --save-dev jest
```

Then, install JSONata:

```bash
npm install jsonata
```

## Create a Basic Script for Testing

Let's create a relatively simple script to get an idea of how Jest works. Start by creating a new directory called `src` and adding a file called `transform.js`:

```bash
mkdir src
touch src/transform.js
```

In `transform.js`, write a function that will accept an `expression` (i.e. a JSONata expression we want to test) and an `input` (a stringified JSON object we want to test):

```javascript
async function transformData(expression, input) {

  const parsedExpression = jsonata(expression);
  const parsedInput = JSON.parse(input);

  let result = await parsedExpression.evaluate(parsedInput);
  
  // convert null to [] for Jest
  result = result ?? [];
  
  // if it's an array, remove any custom properties (like 'sequence') that jsonata may add
  if (Array.isArray(result)) {
    result = JSON.parse(JSON.stringify(result));
  }
  
  return result;
}
```

### Writing Unit Tests for JSONata with Jest

Now, let's write some unit tests and supply some static `expression` and `input` values.

Create a new directory named `__tests__` and add a file called `transform.test.js`:

```bash
mkdir __tests__
touch __tests__/transform.test.js
```

When writing unit tests, it's important we follow a clear structure:

- **Describe Blocks**: Group related tests together using `describe`.
- **Test Cases**: Use `test` or `it` to define individual test cases.
- **Assertions**: Use Jest's `expect` function to check if the result matches the expected output.

In `transform.test.js`, we'll start by creating two tests with hardcoded `expression` and `input` values:

```javascript
const transformData = require('../src/transform');

describe('JSONata Transformation Tests', () => {
  
  // ###################################################################
  // test that validates a specific element always returns a value range
  // ###################################################################

  test('should return true as temperature is always > 20', async () => {

    const expression = "$.body.temperature > 20";

    const input = `
    {
      "body": {
        "temperature": 25
      }
    }`;

    const result = await transformData(expression, input);
    expect(result).toEqual(true);

  });

  // #################################################
  // test that validates the format of the json object
  // #################################################

  test('should correctly return formatted json regardless of values', async () => {
    const expression = "$.body.temperature > 20";

    const input = `
    {
      "body": {
        "temperature": 25
      }
    }`;

    const result = await transformData(expression, input);
    expect(result).toEqual(true);

  });

});
```

**What are these two tests actually testing?** They demonstrate how you might want to:

1. Test that one or more specific properties of your JSON contains a certain value or range of values.
2. Test that your JSON is transformed into a format that you expect.

### Configuring VS Code

Before we run these tests, there are a few options you have in terms of how and when the tests are run.

To ensure a seamless development experience, I recommend installing the following VS Code extensions:

- [Jest](https://marketplace.visualstudio.com/items?itemName=Orta.vscode-jest): Provides syntax highlighting and automatic test running.
- [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint): Helps maintain consistent code style.

#### Option 1: Run on Save

Add the following setting to your `settings.json` file in VS Code. This can be applied on a [user or workspace level](https://code.visualstudio.com/docs/getstarted/settings), it's up to you.

This configuration will automatically run tests every time you save a file:

```json
{
  "jest.autoRun": {
    "watch": true,
    "onSave": "test-file"
  }
}
```

#### Option 2: Manually Initiate Test Runs

Update your `package.json` to include the following:

```json
"scripts": {
  "test": "jest"
}
```

Then, manually run the tests by executing:

```bash
npm test
```

#### Test Results

No matter how you set it up, when you run the tests they should pass with flying colors:

```unknown
PASS  __tests__/transform.test.js

Test Suites: 2 passed, 2 total
```

## Testing JSONata Expressions in Notehub

Building static tests is one thing, but in the real world we work with dynamic data and JSONata expressions that could break our device-to-cloud dataflow with Notecard and Notehub.

Luckily, using the [Notehub API](https://dev.blues.io/api-reference/notehub-api.md) we can:

1. Get a JSONata expression from a Route.
2. Get one or more Events from a Notehub project.
3. Programmatically test the expression against the Event.

Let's extend our existing Node.js project to utilize the Notehub API.

First, install [Axios](https://axios-http.com/), which will let us make HTTP calls to the Notehub API:

```bash
npm install axios
```

Next, create a new file in the `__tests__` directory specific for our Notehub tests:

```bash
touch __tests__/notehub.test.js
```

In this new `notehub.test.js` file, add some require statements:

```javascript
const axios = require('axios');
const transformData = require('../src/transform');
```

Next, create a function that will get a new [auth token](https://dev.blues.io/api-reference/notehub-api.md#authentication-with-oauth-bearer-tokens) from Notehub, based on the `client_id` and `client_secret` provided in your Notehub project's settings:

```javascript
async function getNotehubAuthToken() {
  const tokenUrl = 'https://api.notefile.net/oauth2/token';

  const params = new URLSearchParams({
    grant_type: 'client_credentials',
    client_id: 'your-client-id',
    client_secret: 'your-client-secret',
  });

  const response = await axios.post(tokenUrl, params, {
    headers: {
      'content-type': 'application/x-www-form-urlencoded'
    }
  });

  return response.data.access_token;
}
```

The next step is to create a function that will return a JSONata expression from a known Route in your Notehub project.

```javascript
async function getJSONAtaExpression() {
  try {
    const accessToken = await getNotehubAuthToken();
    const projectUID = 'app:9a442885-d04d-4f5d....';
    const routeUID = 'route:214a8c8c25b2647....';
    const url = `https://api.notefile.net/v1/projects/${projectUID}/routes/${routeUID}`;

    const response = await axios.get(url, {
      headers: {
        Authorization: `Bearer ${accessToken}`
      }
    });

    return String(response.data.http.transform.jsonata);

  } catch (error) {
    console.log(error);
  }
}
```

> **Note:**
>
> You can get the required `projectUID` from your Notehub project's settings or by using the [Get Projects API](https://dev.blues.io/api-reference/notehub-api/project-api.md#get-projects).
>
> Likewise, you can get the `routeUID` from the URL when you navigate to edit your Route in the Notehub UI or by using the [Get Routes API](https://dev.blues.io/api-reference/notehub-api/route-api.md#get-routes).

Next, we'll want to test against one or more Events from a Notehub project. The following function simply gets the most recent Event. This may or may not be what you want, but you can consult the [Event API documentation](https://dev.blues.io/api-reference/notehub-api/event-api.md) to customize this API call for your needs.

```javascript
async function getLatestEvent() {
  try {
    const accessToken = await getNotehubAuthToken();
    const projectUID = 'app:9a442885-d04d-4f5d....';
    const url = `https://api.notefile.net/v1/projects/${projectUID}/events`;

    const response = await axios.get(url, {
      headers: {
        Authorization: `Bearer ${accessToken}`
      }
    });

    return JSON.stringify(response.data.events[0].body);

  } catch (error) {
    console.log(error);
  }
}
```

Lastly, this function runs a test on the specified Event, using the JSONata expression pulled from the Route:

```javascript
async function testLatestEvent() {

  describe('JSONata Transformation Tests', () => {

    test('should correctly return a voltage regardless of value', async () => {
    
      const expression = await getJSONAtaExpression();
      const input = await getLatestEvent();
      const result = await transformData(expression, input);
  
      expect(result).toEqual(
        expect.objectContaining({
          voltage: expect.anything()
        })
      );
    
    });
  });
}

testLatestEvent();
```

Save this file and run your tests again! Hopefully they pass...

```bash
PASS  __tests__/transform.test.js
PASS  __tests__/notehub.test.js

Test Suites: 2 passed, 2 total
Tests:       3 passed, 3 total
Snapshots:   0 total
Time:        1.676 s, estimated 2 s
Ran all test suites.
```

## Best Practices for Unit Testing JSONata

As your projects scale in Notehub, it's critical to ensure your JSONata expressions are covered with unit tests. Consider the following best practices when testing Notehub Events:

- **Cover Edge Cases**: Write tests for edge cases, such as missing elements from an Event or data that is outside the range you expect.
- **Use Meaningful Test Data**: Use test Events from Notehub that reflect real-world scenarios from your devices to ensure your tests are realistic and effective.
- **Isolate Tests**: Don't just copy my spaghetti code above! Each test you write should be independent, focusing on individual aspects of your JSONata expression and the Event(s) you are testing.

## Conclusion

Unit testing JSONata expressions from Notehub with Jest and VS Code provides a reasonably easy way to ensure your data transformations are accurate and reliable. By following the steps outlined in this article, you can set up your VS Code environment, write comprehensive tests, and deploy with confidence.

Happy Hacking! 💙
