Testing7% of the exam

Making unit tests effective

A defect-pattern method for the exam's test-critique questions: spot tests that pass without testing (unreached assertions, unawaited promises, self-made expected values, mocked code under test), tests that fail correct code (identity comparison, floating point, the clock, shared state), and fix them with the right assertion, boundary cases and testable design.

Official exam objective
With a block of code and the associated Unit Test, determine where the test is ineffective and modify it to make it more effective.

~6 min read · 21 practice questions ·

What the exam expects

  • Given a function and its unit test, find why the test passes for broken code or fails for correct code.
  • Choose the assertion that exposes the defect: strictEqual, deepStrictEqual, throws, rejects, an exact count, or a tolerance.
  • Add the missing cases: boundaries, every branch, inputs that distinguish right from wrong formulas, the error path.
  • Make tests deterministic and independent: control the clock, stub external services, reset state with hooks.
  • Refactor code for testability: return values instead of logging, inject dependencies.

Key terms: false pass (a test that passes although the code is wrong); vacuous test (one whose assertion never executes); stub/mock (a stand-in that replaces a dependency with known behaviour); spy (a stand-in that records how it was called); deterministic (same result in any order, any number of times).

Key facts

strictEqual comparison
Detail
Object.is()
deepStrictEqual
Detail
Own enumerable properties, recursively; primitives by Object.is()
Legacy mode (node:assert)
Detail
equal and deepEqual use ==
console.assert()
Detail
Writes "Assertion failed"; does not affect execution
Sync test function
Detail
Fails only if it throws
Promise-returning test
Detail
Fails if the promise rejects
beforeEach / after
Detail
Before each test / once after the suite
sort()
Detail
Sorts in place, returns the same array
0.1 + 0.2
Detail
0.30000000000000004
Sources for this section (5)
  • Why does `assert.strictEqual(fn(), { a: 1 })` fail even when `fn` returns `{ a: 1 }`?
  • When does a synchronous test function pass?
  • Why can a test with assertions inside `forEach` pass for a function that returns nothing useful?
  • Which assertion checks that an async function rejects with a `RangeError`?

The questions are free to read. Answers with their sources and self-grading are included with the pack.

Keep reading with the JavaScript Developer pack

  • Core concepts
  • Exam traps
  • Worked scenario

The pack includes:

  • All 24 lessons of the JavaScript Developer guide, with reading progress
  • Interactive decision walks and step-by-step sequence steppers
  • Inline practice questions and one-click topic practice (21 questions for this lesson)
  • An official source cited for every claim
  • An AI tutor that answers from the guide
  • Unlimited timed practice exams

Practice for the JavaScript Developer exam