mysql2 and Supertest for Express route testing.
What Is Unit Testing
A unit test tests the smallest piece of code in isolation — typically a single function or controller method. “Isolation” means dependencies (MySQL pool, other modules) are replaced with controlled fakes (mocks).The Testing Pyramid
Install Jest and Supertest
Test File Naming
user.test.jsauth.spec.js__tests__/user.js
Jest Basics
Common Matchers
Testing a Pure Function
Mocking mysql2
When testing controllers, you mock the database pool so tests never touch a real MySQL server.Mocking Patterns Reference
Supertest: Testing Express Routes
Supertest sends real HTTP requests to your Express app without starting a server.Setup and Teardown Hooks
Code Coverage
Aim for 80%+ coverage on controller and service files.
TDD: Test-Driven Development
1
Red
Write a failing test before writing the code. It fails because the function doesn’t exist yet.
2
Green
Write the minimum code to make the test pass.
3
Refactor
Improve the code while keeping all tests green.
Key Terms
Common Mistakes
Not exporting app without app.listen()
Not exporting app without app.listen()
If app.js calls app.listen(), Supertest imports it and starts a real server. Export the app separately and have a server.js that calls app.listen(). Only import the app in tests.
Not clearing mocks between tests
Not clearing mocks between tests
Uncleaned mocks from one test leak into the next. Use jest.clearAllMocks() in beforeEach so each test starts fresh.
Mocking pool.execute with wrong return shape
Mocking pool.execute with wrong return shape
mysql2’s pool.execute returns [rows, fields] as an array of two items. Your mock must return the same shape: mockResolvedValueOnce([[rows], []]). A flat array [rows] will make destructuring return the wrong values.
Testing implementation details
Testing implementation details
Tests should check what a function does (correct response, correct SQL called), not how it does it internally. Tests tied to internal logic break every refactor.