DEV Community

Cover image for Mastering Jest: A Beginner's Guide to JavaScript+NodeJs Testing with Fun Examples -1
Monoj Kumar Das
Monoj Kumar Das

Posted on

1 1 1

Mastering Jest: A Beginner's Guide to JavaScript+NodeJs Testing with Fun Examples -1

Writing code is fun, but debugging is painful! Jest helps us catch bugs early and ensures our JavaScript code works correctly.

In this post, I am going to explain how i understood Jest in a most easiest way possible for testing back end apis.
By the end of this post, you’ll understand how to use Jest to test your JavaScript code, APIs, and more—without pulling your hair out!

Table of Contents

  1. Why Do We Need Jest?
  2. Installing Jest
  3. Writing Your First Test
  4. Matchers in Jest
  5. Testing APIs with Jest
  6. Testing Asynchronous Code
  7. Mocking Functions
  8. Real-World Example: Testing a Product Management System
  9. Conclusion

The first question that came to my mind was -

Why Do We Need Jest? Can’t We Just Test APIs by Running Them?

_

Jest is like a robot helper for programmers
. Imagine you’re building a cool app, like a game or a website. You want to make sure everything works perfectly before you show it to your friends. But checking every single part of your app by hand would take forever! That’s where Jest comes in.

Jest is a tool that automatically tests your code to make sure it does what it’s supposed to do. It’s like having a robot that plays with your app, clicks buttons, and checks if everything works correctly._

  1. It’s Faster

    Imagine you have 100 buttons in your app. Testing each one by hand would take hours. Jest can test all of them in seconds!

    Jest runs all your tests automatically, so you don’t have to click around or type commands over and over.

  2. It’s Smarter

    Jest can test every little detail of your code. For example:

    Does this function return the right number?
    
    Does this API return the correct data?
    
    What happens if someone tries to break your app by sending weird inputs?
    

    Jest can handle all these scenarios without you lifting a finger.

  3. It Catches Mistakes

    Sometimes, when you change your code, you accidentally break something. Jest helps you catch these mistakes before they become big problems.

    For example, if you change a function and it stops working, Jest will tell you right away.

  4. It Works for Everything

    Jest isn’t just for APIs. It can test:

    Functions (like math calculations)
    
    Components (like buttons or menus in a website)
    
    APIs (like the ones that fetch data from a server)
    

    It’s like a Swiss Army knife for testing!

  5. It’s Fun!

    Writing tests with Jest is like solving puzzles. You write little challenges for your code, and Jest checks if your code can solve them.
    It’s also super satisfying when all your tests pass and you know your app is working perfectly.

🔹 Installing Jest

npm install --save-dev jest

The keywords in JEST can be easily understandable as they have the exact literal meaning as its supposed to.

Writing Your First Test

Let's say you have a function sum.js that you want to test:
function sum(a, b) {
return a + b;
}
module.exports = sum;

You can write a test for this function by creating a file named sum.test.js:
const sum = require('./sum');
test('adds 1 + 2 to equal 3', () => {
expect(sum(1, 2)).toBe(3);
});

Running Your Tests
Add the following section to your package.json:
{
"scripts": {
"test": "jest"
}
}

Then, you can run your tests using:
npm test or npm run test.

Matchers in Jest

Jest uses "matchers" to let you test values in different ways. The most common matchers are:

toBe uses Object.is to test exact equality.

toEqual recursively checks every field of an object or array.

toBeNull matches only null.

toBeUndefined matches only undefined.

toBeDefined is the opposite of toBeUndefined.

toBeTruthy matches anything that an if statement treats as true.

toBeFalsy matches anything that an if statement treats as false.
Enter fullscreen mode Exit fullscreen mode

Testing APIs with Jest

📝 Example: API Testing Without Jest vs. With Jest
Imagine building a vending machine that sells snacks. You want to make sure it works perfectly before customers start using it. But manually testing every button and snack combination would take forever. Enter Jest—your robot helper for testing!

❌ Manually Testing an API (Like Pressing Buttons Yourself)
1.Open Postman or a browser.
2.Make a request: GET /snacks/1
3.Check if you get: { "id": 1, "name": "Chips", "price": 10 }
Repeat for every snack/api endpoints in your database. 😫

✅ Jest Testing the API (Like a Robot Checking Everything for You):

const { app } = require('../index');
test('GET /snacks/:id should return the correct snack', async () => {
  const response = await request(app).get('/snacks/1');
  expect(response.status).toBe(200);
  expect(response.body).toEqual({ id: 1, name: "Chips", price: 10 });
});
Enter fullscreen mode Exit fullscreen mode

Testing Asynchronous Code

Jest has several ways to handle asynchronous code:
Promises
Return a promise from your test, and Jest will wait for that promise to resolve:

test('the data is peanut butter', () => {
  return fetchData().then(data => {
    expect(data).toBe('peanut butter');
  });
});
Enter fullscreen mode Exit fullscreen mode

Async/Await
Or you can use async and await in your tests:

test('the data is peanut butter', async () => {
  const data = await fetchData();
  expect(data).toBe('peanut butter');
});
Enter fullscreen mode Exit fullscreen mode

Mocking Functions

Jest can mock functions to isolate them from actual API calls or external dependencies.

const fetchData = jest.fn(() => "Mocked Data");

test('mock function test', () => {
  expect(fetchData()).toBe("Mocked Data");
  expect(fetchData).toHaveBeenCalledTimes(1);
});

Enter fullscreen mode Exit fullscreen mode

Now, here it gets interesting..
Lets understand with an example.

Real-World Example: Testing a Product Management System

🛍️** Testing Product Management with Jest**

Imagine you're building an online store, and you have a list of products like Laptops, Coffee Makers, and Shoes. You want to test if:

✅ Your store returns all available products.
✅ You can fetch a product using its ID.
✅ The function returns undefined if a product doesn't exist.
✅ You can add a new product, and the total count increases.

1️⃣ Checking All Products

This test verifies that four products exist in the store initially.
It compares the actual product list with an expected array.
Enter fullscreen mode Exit fullscreen mode

2️⃣ Getting a Product by ID

It tests if ID 1 returns a Laptop from the store.
Enter fullscreen mode Exit fullscreen mode

3️⃣ Handling Non-Existent Products

It checks if an invalid ID 99 correctly returns undefined.
Enter fullscreen mode Exit fullscreen mode

4️⃣ Adding a New Product

It adds a new Tablet to the store.
The test ensures the new product has an ID (5) and the total product count increases.
Enter fullscreen mode Exit fullscreen mode

🖼️ Illustration: How the Test Works

here's the code representation of this concept -

getProducts() → Retrieves all products.
getProductById(id) → Fetches a specific product by its id.
addProduct(product) → Adds a new product to the list.

These functions are already defined in Product.js file.

let products = [
  { id: 1, name: 'Laptop', category: 'Electronics' },
  { id: 2, name: 'Coffee Maker', category: 'Appliances' },
  { id: 3, name: 'Headphones', category: 'Electronics' },
  { id: 4, name: 'Running Shoes', category: 'Footwear' },
];

function getProducts() {
  return products;
}

function getProductById(id) {
  return products.find(product => product.id === id);
}

function addProduct(product) {
  const newProduct = { id: products.length + 1, ...product };
  products.push(newProduct);
  return newProduct;
}

module.exports = { getProducts, getProductById, addProduct };
Enter fullscreen mode Exit fullscreen mode

products.test.js

const { getProducts, getProductById, addProduct } = require('../product');

describe('Products Functions', () => {
 // All tests related to products go inside the describe block.
  it('should return all products', () => {
//Each it() function represents a single test case.
    let products = getProducts();
    console.log('Initial Products:', products);
    expect(products.length).toEqual(4);
//expect() is used to compare actual vs expected results.
    expect(products).toEqual([
      { id: 1, name: 'Laptop', category: 'Electronics' },
      { id: 2, name: 'Coffee Maker', category: 'Appliances' },
      { id: 3, name: 'Headphones', category: 'Electronics' },
      { id: 4, name: 'Running Shoes', category: 'Footwear' },
    ]);
  });

  it('should return a product by id', () => {
    let product = getProductById(1);
    console.log('Product Retrieved:', product);
    expect(product).toEqual({
      id: 1,
      name: 'Laptop',
      category: 'Electronics',
    });
  });

  it('should return undefined for non-existent product', () => {
    let product = getProductById(99);
    console.log('Non-existent Product:', product);
    expect(product).toBeUndefined();
//getProductById(99) is called, but product ID 99 does not exist.
  });

  it('should add a new Product', () => {
    let newProduct = { name: 'Tablet', category: 'Electronics' };
    let addedProduct = addProduct(newProduct);
    console.log('Product Added:', addedProduct);
    expect(addedProduct).toEqual({
      id: 5,
      name: 'Tablet',
      category: 'Electronics',
    });

    let products = getProducts();
    console.log('Updated Products:', products);
    expect(products.length).toEqual(5);
  });
});
Enter fullscreen mode Exit fullscreen mode

Without Jest, you would have to manually:

Run `getProducts()`, check if the output is correct.
Call `getProductById(1)`, manually verify if it returns the correct product.
Add a product, then check the list manually.
Enter fullscreen mode Exit fullscreen mode

🔥 Jest automates all of this, runs the tests, and gives clear results showing which tests passed or failed!

running npm run test will give

You didn't understand or if u skipped the code. Just read the code like a paragraph. its that easy.

Common Jest Errors:
Even with Jest, you may run into errors while testing. Here are a few common ones and their solutions:

1️⃣ TypeError: Cannot read properties of undefined (reading 'xyz')
🔍 Cause: You're trying to access a property of an undefined object.
🔍 Cause: Your test expectation doesn't match the actual output.
🔍 Cause: Your test contains an unresolved async operation (e.g., missing await).
🔍 Cause: Your test expects a function to be called, but it's not.
✅ Fix:
Ensure your function handles missing data properly, or check if mock data is initialized correctly.Print the actual output using console.log() before expect() to debug the issue.

Conclusion

Testing your code doesn’t have to be a chore—it can actually be fun and rewarding! With Jest, you can automate the tedious parts of testing, catch bugs early, and ensure your code works exactly as expected. Whether you’re testing simple functions, complex APIs, or even entire applications, Jest is your trusty robot helper that makes the process fast, reliable, and even enjoyable.

⬆️ Back to Top
To continue with Mock functions, tune to part 2 >>>

Heroku

Amplify your impact where it matters most — building exceptional apps.

Leave the infrastructure headaches to us, while you focus on pushing boundaries, realizing your vision, and making a lasting impression on your users.

Get Started

Top comments (0)

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

👋 Kindness is contagious

Engage with a wealth of insights in this thoughtful article, valued within the supportive DEV Community. Coders of every background are welcome to join in and add to our collective wisdom.

A sincere "thank you" often brightens someone’s day. Share your gratitude in the comments below!

On DEV, the act of sharing knowledge eases our journey and fortifies our community ties. Found value in this? A quick thank you to the author can make a significant impact.

Okay