How do you structure tests with Jest (or Mocha)? Assertions and lifecycle hooks.
3 minbeginnernodejsjestmochaassertionstest-structure
Quick Answer
Group tests with describe blocks and define cases with test/it. Use matchers (expect(x).toBe(...)) for assertions and lifecycle hooks (beforeAll/afterAll, beforeEach/afterEach) for setup and teardown. Jest is an all-in-one framework (runner + assertions + mocks); Mocha pairs a runner with libraries like Chai and Sinon.
Detailed Answer
Answer:
Structure — describe groups, test/it cases:
describe('UserService', () => {
let service;
beforeEach(() => { // fresh state per test
service = new UserService(fakeRepo);
});
test('creates a user', async () => {
const user = await service.create({ name: 'Alice' });
expect(user.id).toBeDefined();
expect(user.name).toBe('Alice');
});
test('rejects a duplicate email', async () => {
await expect(service.create({ email: 'taken@x.com' }))
.rejects.toThrow('already exists');
});
});
Assertions (Jest matchers):
- Equality:
toBe(===, primitives),toEqual(deep),toStrictEqual. - Truthiness:
toBeTruthy,toBeNull,toBeDefined. - Numbers/strings:
toBeGreaterThan,toMatch(/regex/),toContain. - Errors/async:
toThrow,resolves/rejects.
Lifecycle hooks:
| Hook | Runs |
|---|---|
beforeAll / afterAll | once per file (e.g., start/stop a DB) |
beforeEach / afterEach | before/after each test (reset state) |
Jest vs Mocha:
- Jest — batteries-included: runner, assertions (
expect), mocking, coverage, snapshots, parallel execution. Common default for Node/React. - Mocha — just the runner; pair with Chai (assertions) and Sinon (mocks/stubs/spies). More modular/configurable.
- (Node also now ships a built-in
node:testrunner.)
Best practices: keep tests isolated (no shared mutable state — reset in beforeEach), one behavior per test, descriptive names, and avoid depending on test execution order.