18 Jest Interview Questions With Code Answers (2026)
Zamir Khotov January 20, 2026 Updated: November 5, 2026 Interviews & Getting Hired

18 Jest Interview Questions With Code Answers (2026)

📧 Subscribe to JS Pulse

The JavaScript job market in one email: real numbers from 600+ job listings, 5 jobs worth applying to, and what actually changed. Join 9,600+ developers.

Most JavaScript interviews that touch testing never ask you to recite the Jest documentation. They ask you to explain a choice. Why toEqual and not toBe here. Why this mock leaks into the next test. Why the test passes on your machine and fails in CI. The candidates who stumble usually know the API. What they cannot do is say why one approach is right for the situation in front of them.

I run a job board for JavaScript developers, so I read a lot of React and Node job posts. Testing shows up in a large share of them, usually as Jest, Vitest, React Testing Library or Playwright in the requirements list. It rarely gets its own paragraph, which is exactly why candidates underprepare for it. Then the interviewer opens a file with a half-written test and asks you to finish it.

This article collects the Jest interview questions that come up again and again, from the basics to the questions that separate mid-level from senior candidates. Every answer is short enough to say out loud in an interview, and where code helps, there is code. The goal is not to memorize answers. It is to understand each one well enough that a follow-up question does not break you.

If you only have ten minutes, read the mocking section. That is where most Jest interviews go deeper than candidates expect.

Jest Basics Every Interviewer Expects

The basic Jest questions check whether you have actually written tests or only read about them. They are easy to answer well and surprisingly easy to answer vaguely.

What does Jest give you out of the box?

Jest is a test runner, an assertion library and a mocking library in one package. It finds test files, runs them in parallel worker processes, provides expect with its matchers, and includes jest.fn, jest.mock and fake timers without extra dependencies. It also collects coverage. A good answer mentions that this all-in-one design is the reason Jest became the default, and that Vitest later copied most of the same API.

toBe, toEqual or toStrictEqual?

toBe checks identity using Object.is, so two different objects with the same content are not equal. toEqual compares values recursively and ignores properties that are undefined. toStrictEqual is stricter. It treats undefined properties as meaningful and checks that objects have the same class.

const a = { id: 1 };
const b = { id: 1, name: undefined };

expect(a).toBe(a);           // passes, same reference
expect({ id: 1 }).toBe(a);   // fails, different objects
expect(a).toEqual(b);        // passes, undefined is ignored
expect(a).toStrictEqual(b);  // fails, undefined counts

Use toBe for primitives and references, toEqual for most object comparisons, and toStrictEqual when the exact shape of the data matters, for example when testing an API response mapper.

beforeEach or beforeAll?

beforeEach runs before every test in its block, so each test starts from a clean state. beforeAll runs once before all tests in the block, which is useful for expensive setup like starting a test database connection. The interview point is isolation. Shared state created in beforeAll can leak between tests and make their result depend on order, so you should only use it for setup that tests do not modify.

How do you test asynchronous code?

Make the test async and await the code under test, or return the promise from the test. For rejections, use rejects and remember to await it.

test('loads the user', async () => {
  const user = await fetchUser(1);
  expect(user.name).toBe('Ada');
});

test('fails for a missing user', async () => {
  await expect(fetchUser(999)).rejects.toThrow('Not found');
});

The classic mistake interviewers look for is forgetting the await before expect(...).rejects. The test finishes before the promise settles and passes no matter what. If you write a test that checks a rejection inside a try/catch, add expect.assertions(1) so the test fails when the promise unexpectedly resolves. If async code itself still feels shaky, my guide to JavaScript promises and async patterns covers the parts that make these tests tricky.

What does testEnvironment change?

It decides which globals your tests run with. The node environment has no window or document, which is right for backend code. Testing React components needs jsdom, a browser-like environment implemented in JavaScript. Since Jest 28, jest-environment-jsdom is a separate package, so a missing install is a common reason a component test fails with "document is not defined".

What does test.each do?

It runs the same test with different inputs, so you avoid copying a test five times with one value changed. Each row becomes its own test with its own name in the output, which makes failures easy to read.

test.each([
  ['1000', 1000],
  ['1,000', 1000],
  ['', 0],
])('parseAmount(%s) returns %d', (input, expected) => {
  expect(parseAmount(input)).toBe(expected);
});

It is a good place to mention edge cases. Interviewers like to see an empty string, a negative number or an unexpected format in the table, not only the happy path.

Mocking Questions That Decide the Interview

Mocking is where Jest interviews get serious, because bad mocking produces tests that pass while the code is broken. Interviewers use these questions to see whether you understand what a mock replaces and what it costs.

jest.fn, jest.spyOn or jest.mock?

jest.fn creates a new standalone mock function, which you pass in as a callback or dependency. jest.spyOn wraps an existing method on an object, records its calls, and can be restored to the original later. jest.mock replaces an entire module, so every file that imports it during the test gets the mocked version.

const onSave = jest.fn();                      // new mock function
const spy = jest.spyOn(console, 'error');      // wraps a real method
jest.mock('./api');                            // replaces the whole module

A strong answer adds the trade-off. jest.mock is the most powerful and the easiest to overuse, because it hides how your code actually talks to the module.

mockReturnValue or mockImplementation?

mockReturnValue makes the mock return a fixed value. mockResolvedValue makes it return a promise that resolves to that value, which is what you want for mocked async functions. mockImplementation gives the mock real logic, for example returning different results based on the arguments. The Once variants, like mockResolvedValueOnce, apply only to the next call, which is how you test a retry after a failure.

api.getUser
  .mockRejectedValueOnce(new Error('timeout'))
  .mockResolvedValueOnce({ name: 'Ada' });

const user = await loadUserWithRetry(1);
expect(api.getUser).toHaveBeenCalledTimes(2);
expect(user.name).toBe('Ada');

clearAllMocks, resetAllMocks or restoreAllMocks?

This question catches many candidates. clearAllMocks wipes the recorded calls and results but keeps any implementation you set. resetAllMocks does that and also removes the implementations, so mocks return undefined again. restoreAllMocks puts back the original implementation for functions you mocked with jest.spyOn.

The practical answer is that leaking mock state between tests is one of the most common sources of tests that pass alone and fail together. Calling one of these in afterEach, or setting clearMocks or restoreMocks in the Jest config, prevents it.

How do you mock only part of a module?

Use jest.requireActual inside the factory to keep the real exports and override only the one you need.

jest.mock('./utils', () => ({
  ...jest.requireActual('./utils'),
  getCurrentDate: jest.fn(() => new Date('2026-01-01')),
}));

Interviewers often follow up with why jest.mock calls work even though they appear below the imports. With babel-jest, they are hoisted to the top of the file. That is also why variables used inside the factory must be prefixed with mock or defined inside it.

How do you test code that uses setTimeout?

Use fake timers so the test controls time instead of waiting for it.

jest.useFakeTimers();

test('shows the toast for 3 seconds', () => {
  showToast('Saved');
  expect(isToastVisible()).toBe(true);

  jest.advanceTimersByTime(3000);
  expect(isToastVisible()).toBe(false);
});

jest.advanceTimersByTime moves the clock by a set amount, jest.runAllTimers flushes everything that is pending, and jest.useRealTimers switches back. A senior candidate mentions that fake timers and promises interact in non-obvious ways, so code that awaits inside a timer callback may need await jest.advanceTimersByTimeAsync(3000) instead.

Jest With React Testing Library

For frontend roles, Jest questions almost always come together with React Testing Library questions. The interviewer wants to see that you test what the user sees, not how the component is built. The rest of a frontend interview is covered in this React developer interview guide.

getBy, queryBy or findBy?

getBy returns the element or throws if it is missing, so it is the default for elements that should be there. queryBy returns null instead of throwing, which is the right tool for asserting that something is not rendered. findBy returns a promise and waits for the element to appear, which is what you use after an async action like a data fetch.

render(<UserProfile id={1} />);

expect(screen.getByText('Loading...')).toBeInTheDocument();
expect(await screen.findByText('Ada Lovelace')).toBeInTheDocument();
expect(screen.queryByText('Loading...')).not.toBeInTheDocument();

Preferring getByRole over getByTestId is a good point to make, because role queries also check that the component is accessible.

How do you test a component that fetches data?

Mock at the network boundary, not inside the component. You can mock the module that does the fetching with jest.mock, or intercept requests with a tool like Mock Service Worker, which keeps the component code untouched. Then test the three states the user sees: loading, success and error.

The answer that stands out explains why. Mocking the network keeps the test close to how the component really behaves, so a refactor of the component internals does not break the test.

How do you test a custom hook?

Test it through renderHook from React Testing Library, which renders the hook inside a small test component and gives you its current return value. Wrap state changes in act so React finishes updating before you assert.

import { renderHook, act } from '@testing-library/react';

test('counter increments', () => {
  const { result } = renderHook(() => useCounter(0));
  act(() => result.current.increment());
  expect(result.current.count).toBe(1);
});

A thoughtful follow-up is that a hook used by only one component is often better tested through that component. renderHook shines for shared hooks with their own logic, like data fetching or form state.

When are snapshot tests a good idea?

Rarely, and for small, stable output. A snapshot of a short formatted string or a small serialized object is useful. A snapshot of a whole page component is not, because it changes with every markup edit and people learn to update it with jest -u without reading the diff. toMatchInlineSnapshot keeps small snapshots inside the test file where reviewers actually see them. Saying that you use snapshots sparingly is usually the answer interviewers hope for.

Questions for Senior Candidates

Senior Jest questions are less about the API and more about judgment. There is no single right answer, and the interviewer listens for how you reason.

Jest or Vitest in 2026?

Both are reasonable, and the honest answer depends on the project. Vitest is built on Vite and runs naturally in projects that already use it. It deliberately keeps a Jest-compatible API, with vi.fn and vi.mock in place of jest.fn and jest.mock, so moving between them is mostly mechanical. Jest remains common in existing codebases and many Next.js and Node projects. Knowing both, and knowing that the concepts transfer, is worth more than having a strong opinion about either.

What would you not test?

Third-party libraries, framework internals, trivial getters and implementation details like the internal state of a component. Testing those adds maintenance cost without catching real bugs. Coverage numbers are useful for finding untested logic, but chasing a percentage leads to tests that execute code without checking anything meaningful. A senior answer names the parts of the system where a bug would hurt most and starts there.

Why does a test fail only in CI?

Start with what differs between the two environments. Order dependence, where tests share state and pass only in a certain sequence, is the most common cause, so try running the failing test alone and the full suite with --runInBand. Then check time and timezone assumptions, real timers or network calls that are not mocked, and environment variables. Tests that depend on Date.now() or the machine timezone are frequent offenders, which is another reason to control time with fake timers.

What Interviewers Actually Listen For

The common advice is to memorize a list of Jest questions, and I think that advice is wrong. A memorized answer survives the first question and falls apart on the follow-up. Interviewers who ask about testing are rarely checking whether you know mockResolvedValueOnce exists. They are checking whether you would write tests that the rest of the team can trust. You can see the same pattern in what interviewers actually write about you after an interview.

That shows up in small things. You explain why a mock is there, not only how to write it. You notice when a test checks the implementation instead of the behavior. You mention isolation before the interviewer asks about flaky tests. You admit when something is a trade-off instead of pretending there is one correct tool.

It also shows up in what you skip. A candidate who wants to test every line looks less senior than one who says where testing pays off and where it does not. Teams hiring for React and Node roles are not short of people who can write a test. They are short of people whose tests catch real bugs and do not break on every refactor.

Before Your Next Interview

Pick one small function and one small component from a project you know, and write tests for both from scratch without looking at the docs. Then explain each test out loud as if someone asked why it exists. That exercise prepares you better than any list, including this one, because it is exactly what a live testing interview feels like.

Most of the questions above have a short answer and a better answer. The short answer names the API. The better answer explains the trade-off. If you can give the better answer for the mocking questions, you are already ahead of most candidates who list Jest on their CV.

Knowing Jest gets you through the question, but explaining why you would write the test that way is what gets you the offer.

I write about what JavaScript companies actually test and ask for in JS Pulse, my newsletter for JavaScript developers. You can subscribe here, or browse current JavaScript jobs that list testing in their requirements.

📧 Subscribe to JS Pulse

The JavaScript job market in one email: real numbers from 600+ job listings, 5 jobs worth applying to, and what actually changed. Join 9,600+ developers.

Related articles

CI/CD for JavaScript Developers in 2026 and Why Your Deployment Pipeline Is the Skill Gap Costing You Senior Roles
infrastructure 8 months ago

CI/CD for JavaScript Developers in 2026 and Why Your Deployment Pipeline Is the Skill Gap Costing You Senior Roles

67% of senior JavaScript developer job postings on major platforms now list CI/CD experience as a requirement. Not a nice-to-have. A requirement. Two years ago that number was closer to 40%. The shift happened quietly while most frontend developers were focused on frameworks and state management.

David Koy Read more
Debugging JavaScript Like a Detective: A Systematic Approach to Finding and Fixing Bugs
infrastructure 9 months ago

Debugging JavaScript Like a Detective: A Systematic Approach to Finding and Fixing Bugs

The production app is broken. Users are complaining. Your manager is asking for updates every fifteen minutes. Everyone is looking at you.

John Smith Read more
Docker for JavaScript Developers in 2026 and The Infrastructure Skill Missing From Your Resume That&#039;s Costing You the Senior Role
infrastructure 8 months ago

Docker for JavaScript Developers in 2026 and The Infrastructure Skill Missing From Your Resume That's Costing You the Senior Role

Entry-level JavaScript hiring is down 60% compared to two years ago. Companies are not posting fewer jobs because the work disappeared. They are posting fewer junior and mid-level roles because they now expect the people they hire to cover more ground. And one of the first places that gap shows up in interviews, in take-home assignments, and in day-to-day team work is infrastructure. Specifically: Docker.

David Koy Read more