Writing Unit Tests
Writing Unit Tests — why it matters
A unit test exercises one behavior with controlled inputs and explicit expectations. Arrange the inputs, act by calling the unit, then assert an observable result. Test edge cases and failure paths rather than only the happiest example.
What you’ll learn
- Explain writing unit tests and the problem it solves.
- Identify the relevant compile-time checks and runtime responsibilities.
- Run the example, predict its output, and try a realistic modification.
Understand the mechanism
The table drives three independent checks, including the boundary at age 18. Throwing stops execution if the observed result differs from the declared expectation.
A test that only prints a result without comparing it to an expected value may not detect regressions.
Follow the concept flow
Run the primary TypeScript example
Save as writing-unit-tests.ts. The following program passed strict TypeScript compilation, and the displayed output was captured by executing its emitted JavaScript with Node.js 22.16.0.
TypeScript source
function isAdult(age: number): boolean { return age >= 18; }
const cases = [{ input: 17, expected: false }, { input: 18, expected: true }, { input: 30, expected: true }];
for (const test of cases) {
if (isAdult(test.input) !== test.expected) throw new Error(`Age ${test.input} failed`);
}
console.log(`${cases.length} unit cases passed`);Verified output
3 unit cases passedCompile: npx tsc --strict --target es2022 --module commonjs writing-unit-tests.ts; run: node writing-unit-tests.js. For Node.js API examples, install @types/node first. For browser projects, use the browser-specific instructions below.
The example demonstrates the code-level behavior; the related configuration or test commands are shown separately when needed.
Trace the result
The table drives three independent checks, including the boundary at age 18. Throwing stops execution if the observed result differs from the declared expectation.
Predict what changes if you alter one input. Then run the code to compare your reasoning with the real output.
Try the full tool or configuration workflow
Practical project lab: These are real configuration and source-file examples, not a TypeScript object that merely describes settings. Place the files at the named paths relative to one project directory.
age.ts
export const adult = (age:number) => age>=18;age.test.ts
import { test } from "node:test";
import { strict as assert } from "node:assert";
import { adult } from "./age";
test("boundary",()=> { assert.equal(adult(17),false); assert.equal(adult(18),true); });Commands
npx tsc --strict --module commonjs --target es2022 age.ts age.test.ts
node --test age.test.jsUse separate cases with names and assertions to improve failure messages.
This local compiler or test-runner mini-project was validated in addition to the primary program.
Common mistake and correction
A test that only prints a result without comparing it to an expected value may not detect regressions.
Identify whether the failure is a type-checking issue, a configuration issue, or a runtime behavior issue before choosing a fix.
Practice the concept
Add cases for age 0 and a negative age; decide whether negative input should throw or return false.
Write down your expected result first. For configuration examples, compare compiler output and diagnostics; for test examples, make the assertion fail deliberately to verify that the tool reports it.
Check your understanding
What to remember
A unit test exercises one behavior with controlled inputs and explicit expectations.
Run the primary example, then complete the practice task or environment-specific lab.
Reaching the recap and completing the quizzes are separate milestones.