Unit Testing Documentation (Jest) - melcholign/harvest-cart GitHub Wiki

What is Unit Testing?

Unit testing is a software testing technique that focuses on verifying the functionality of individual components or units of code, such as functions, methods, or classes, in isolation from the rest of the application. It ensures that each unit performs as expected under various scenarios, including edge cases and error conditions. By writing unit tests, developers can catch bugs early, improve code reliability, and simplify debugging.

What is Jest?

Jest is a powerful testing framework for JavaScript that simplifies testing functions and controllers. This guide provides an overview of testing simple functions and controller code with concepts from the provided code.

Setting Up Jest

Prerequisites

  • Node.js installed.

Installation

  • Install Jest using npm.
npm install --save-dev jest

Configuration

  • Enable Node’s experimental ESM support by adding this flag to your test script in package.json.
{
  "scripts": {
    "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
  }
}

Writing Tests with Jest

Test File Naming

  • Use .test.js suffix, e.g., example.test.js.
  • Store test files in a tests directory or alongside the files being tested.

Basic Example

  • Write a test in math.test.js for a function that adds two numbers exported by math.js:
import { add } from './math';

test('adds 1 + 2 to equal 3', () => {
  expect(add(1, 2)).toBe(3);
});
  • To run test on a specific file,
npm test math.test.js

or, to run tests on all .test.js files in the project directory

npm test

Testing Asynchronous Code

  • Use async/await or return a promise:
test('fetches data successfully', async () => {
  const data = await fetchData();
  expect(data).toBeDefined();
});

Testing Controllers

Controller tests often involve mocking HTTP request/response objects and external resources (e.g., databases).

Concepts from Example Code

The provided code demonstrates:

  • Database Setup and Cleanup: Insert mock data before tests and remove it after.
  • Mocked HTTP Objects: Use jest.fn() to mock methods like res.status and res.json.
  • Assertions: Verify controller behavior with expect.
import { jest } from '@jest/globals';
import { pool } from '../../db/pool.js';
import { BasketController } from '../../controllers/basket-controller.js';
import { executeQueries } from './test-functions.js';

test('Retrieving valid basket, with information on its changes', async () => {
  const connection = await pool.getConnection();

  // Insert mock data
  await executeQueries(connection, [
    `
    INSERT INTO Product(productId, productName, stockQuantity, price)
    VALUES (1000, 'Egg', 100, 15),
           (1001, 'Chicken', 25, 200),
           (1002, 'Cabbage', 97, 39)
    `,
    `
    INSERT INTO Basket(customerId, productId, productQuantity)
    VALUES (1, 1000, 10)
    `,
  ]);

  // Mock request and response
  const req = {
    user: { customerId: 1 },
  };

  const res = {
    status: jest.fn().mockReturnThis(),
    json: jest.fn(),
  };

  // Test the controller
  await BasketController.getBasket(req, res);

  // Verify the response
  expect(res.json).toHaveBeenCalledWith({
    basket: [
      {
        id: 1000,
        name: 'Egg',
        category: 'miscellaneous',
        quantity: 10,
        unitPrice: 15,
      },
    ],
    changes: [],
  });

  // Cleanup mock data
  await executeQueries(connection, [
    `DELETE FROM Basket WHERE customerId = 1`,
    `DELETE FROM Product WHERE 1000 <= productId AND productId <= 1003`,
  ]);

  await connection.release();
});

Output

Screenshot from 2024-12-01 17-46-11

Generate HTML Report with jest-html-reporter

To generate an HTML report, you can use jest-html-reporter.

Install the reporter:

npm install --save-dev jest-html-reporter

Configure Jest to Use the Reporter

In package.json, add the following configuration:

{
  "jest": {
    "reporters": [
      "default",
      [
        "jest-html-reporter",
        {
          "pageTitle": "Test Report",
          "outputPath": "./test-report.html",
          "includeFailureMsg": true
        }
      ]
    ]
  }
}

Run Jest to Generate the HTML Report

npm test

The report will be saved to the specified path (./test-report.html in this example).

References

  1. Jest Documentation
  2. jest-html-reporter Documentation