JavaScript Testing

Introduction

Testing JavaScript code ensures your apps don’t break as they grow. The modern JS ecosystem provides powerful testing tools like Jest, Mocha, Vitest, Cypress, and Playwright. This tutorial covers unit tests, integration tests, mocking, and best practices.

1. What Are Unit Tests?

Unit tests check single functions or components.

// example function
function add(a, b) { return a + b; }

// test
test("adds numbers", () => {
  expect(add(2, 3)).toBe(5);
});
    

2. Installing Jest (Node.js)

npm install --save-dev jest
    
Add to package.json:
"scripts": {
  "test": "jest"
}
    

3. Basic Jest Test File

// math.js
export function multiply(a, b) {
  return a * b;
}

// math.test.js
import { multiply } from "./math.js";

test("multiply works", () => {
  expect(multiply(4, 5)).toBe(20);
});
    

4. Testing Asynchronous Code

async function fetchUser() {
  return "Kaloyan";
}

test("async test", async () => {
  const user = await fetchUser();
  expect(user).toBe("Kaloyan");
});
    

5. Mocking Functions

const sendEmail = jest.fn();

test("email sent", () => {
  sendEmail("hello");
  expect(sendEmail).toHaveBeenCalledWith("hello");
});
    

6. Mocking Modules

jest.mock("./api.js", () => ({
  getUser: () => "MockUser"
}));
    

7. Snapshot Testing (UI)

expect(renderedHTML).toMatchSnapshot();
    

8. Using Vitest (Faster Alternative)

npm install -D vitest
    
// test
import { describe, it, expect } from "vitest";

describe("math", () => {
  it("works", () => {
    expect(2 + 2).toBe(4);
  });
});
    

9. Browser Testing (Cypress)

npm install cypress --save-dev
npx cypress open
    

10. E2E Example

// cypress test
cy.visit("https://codetweakrs.net");
cy.contains("Tutorials").click();
    

11. Testing DOM Manipulation

document.body.innerHTML = `
  <button id="btn">Click</button>
`;

document.getElementById("btn").click();
    

12. Testing Fetch Calls

global.fetch = jest.fn(() =>
  Promise.resolve({
    json: () => Promise.resolve({ name: "Kaloyan" })
  })
);

test("fetch user", async () => {
  const res = await fetch("/api");
  const data = await res.json();
  expect(data.name).toBe("Kaloyan");
});
    

13. Code Coverage

npm test -- --coverage
    

14. Useful Assertions

expect(value).toBeDefined();
expect(value).toBeNull();
expect(arr).toContain(10);
expect(obj).toMatchObject({ username: "Kaloyan" });
    

15. Best Practices

Summary