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 bymath.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
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).