Testing & diagnostics (intro) in nodejs
medium · Node.js — Server-side JavaScript
In modern Node.js (version 18+), you no longer need external libraries like Jest or Mocha for basic testing. The built-in node:test module provides a fast, native test runner, and node:mock allows you to track or replace function behavior. 1. The Native Test Runner ( node:test ) This module provides the structure for your tests using test or describe/it blocks. import { test, describe, it } from 'node:test'; import assert from 'node:assert'; describe('Math operations', () => { it('should add two numbers correctly', () => { assert.strictEqual(1 + 1, 2); }); test('subtraction works', () => { assert.strictEqual(5 - 2, 3); }); }); To run these tests, you simply use the command: node --test 2. Mocking with node:mock Mocks are essential when you want to isolate a piece of code. For example, if you are testing a "Welcome Email" function, you don't want to send a real email every time the test runs. You "mock" the email sender. A. Spies (Tracking function calls) A spy tracks how many times a function was called and with what arguments. import { mock, test } from 'node:test'; import assert from 'node:assert'; test('spying on a function', (t) => { const sum = (a, b) => a + b; const mockedSum = t.mock.fn(sum); // Create a tracked version of sum mockedSum(1, 2); mockedSum(3, 4); assert.strictEqual(mockedSum.mock.callCount(), 2); assert.deepStrictEqual(mockedSum.mock.calls[0].arguments, [1, 2]); }); B. Mocking Objects and Modules You can use mock.method to temporarily change how a specific method on an object behaves. import { mock, test } from 'node:test'; import assert from 'node:assert'; const database = { save: (data) => { /* real DB logic here */ } }; test('mocking a database save', (t) => { // Replace 'save' with a fake version that returns true t.mock.method(database, 'save', () => true); const result = database.save({ name: 'Tharun' }); assert.strictEqual(result, true); assert.strictEqual(database.save.mock.callCount(), 1); }); 3. Timers Mocking Testing code that uses setTimeout or setInterval can be slow. Node.js allows you to "fake" time, making a 24-hour delay pass instantly in your test. import { mock, test } from 'node:test'; import assert from 'node:assert'; test('faking time', (t) => { t.mock.timers.enable(); // Take control of time let triggered = false; setTimeout(() => { triggered = true; }, 9999); t.mock.timers.tick(10000); // Fast-forward 10 seconds assert.strictEqual(triggered, true); }); 4. Why use the native API? Zero Dependencies: No need to install npm install jest . Your node_modules stays small. Speed: It starts almost instantly because it doesn't need to load a heavy framework. Standardization: Since it's built into Node.js, your tests are more likely to work across different environments without configuration issues. Feature Feature Purpose Test Block test() or it() Defines a single test case. Grouping describe() Organizes related tests. Function Mock mock.fn() Tracks or replaces a standalone function. Method Mock mock.method() Replaces a method on an existing object. Time Control mock.timers Manipulates setTimeout and setInterval.