Mock objects and fixtures in JavaScript: your testing arsenal
\n\nImagine you are writing a module that sends requests to an external weather API. You run your tests — and they fail because the API is temporarily unavailable. Or worse: you are testing a payment system, and each run charges real money from a card. Sound familiar? Welcome to the world where mock objects and fixtures in JavaScript become your best friends.
\n\nIn this article, we won't just list definitions. We'll break down how to make tests fast, reliable, and independent of the outside world using mocks, stubs, and fixtures. You'll learn how to fake timers, mock HTTP requests, and prepare perfect test data. Let's go!
\n\nWhy do you need mocks and fixtures? The pain and the salvation
\n\nWhen you write JavaScript unit tests, you want to test only one module. But real code often depends on databases, file systems, network calls, or random numbers. Without mocks, every test is a lottery: it can fail due to a network timeout or because the server returned unexpected data.
\n\nMock objects are substitutes for real dependencies. They mimic the behavior of the original objects, but you have full control over their responses. Fixtures are pre-prepared data sets (e.g., a JSON API response) that you plug into your tests. Together, they give you a superpower: you test the logic, not the infrastructure.
\n\nMock vs Stub vs Spy: understanding the terms
\n\nBefore writing code, let's clarify the terminology. In the JavaScript ecosystem (especially in Jest and Mocha), these concepts are sometimes mixed up, but the differences are important:
\n\n- \n
- Mock — an object that replaces a real dependency and allows you to set expected behavior. You say: "When the getUser method is called with id=5, return the object {name: 'Alice'}". \n
- Stub — a simplified version of a mock. It simply returns fixed data without checking how it was called. Often used to replace functions that return random values. \n
- Spy — a wrapper around a real function. It doesn't change its behavior but records how many times it was called, with what arguments, and what it returned. Perfect for checking side effects. \n
In most modern frameworks (Jest, Sinon.js), mocks can do everything: replace implementations and spy. But understanding the difference will help you write more meaningful tests.
\n\nFixtures: how to prepare test data
\n\nFixtures in JavaScript tests are simply data that you extract into separate files or variables. Why is this necessary? First, to avoid duplicating 50-line JSON objects in every test. Second, to quickly change scenarios: one fixture for a successful response, another for an error.
\n\nExample of a simple fixture for testing a user management module:
\n\n// fixtures/users.js\nexport const userAlice = {\n id: 1,\n name: 'Alice',\n email: 'alice@example.com',\n role: 'admin'\n};\n\nexport const userBob = {\n id: 2,\n name: 'Bob',\n email: 'bob@example.com',\n role: 'user'\n};\n\nexport const apiResponseSuccess = {\n status: 200,\n data: { users: [userAlice, userBob] }\n};\n\nexport const apiResponseError = {\n status: 500,\n message: 'Internal Server Error'\n};\n\n\nNow in tests, we simply import these objects. This makes the code cleaner and allows you to easily reproduce cases: "What if the server returned a 500?"
\n\nMock in Jest: practical examples
\n\nJest is the most popular testing framework for JavaScript. It is built into Create React App, Next.js, and many other tools. Let's look at how to create mock objects in Jest.
\n\nMock functions with jest.fn()
\n\nLet's say we have a function that calls a callback after processing data