What if you could catch API bugs before your users do, every time you change code?
Why Testing API routes in NextJS? - Purpose & Use Cases
Imagine you build an API route in Next.js that handles user data. You manually call it in the browser or with curl every time you make a change to check if it works.
Manually testing API routes is slow and unreliable. You might miss edge cases, forget to test error handling, or waste time repeating the same steps. It's easy to introduce bugs without noticing.
Testing API routes with automated tests lets you quickly check all cases, catch bugs early, and confidently change code knowing your API still works as expected.
curl http://localhost:3000/api/user
// Check response manuallyimport { createMocks } from 'node-mocks-http'; import handler from '../pages/api/user'; const { req, res } = createMocks({ method: 'GET' }); await handler(req, res); expect(res._getStatusCode()).toBe(200);
Automated API route testing enables fast, repeatable, and reliable checks that keep your backend stable and bug-free.
A developer updates the user login API. With tests, they quickly verify the login still works and handles errors without manually trying every scenario.
Manual API testing is slow and error-prone.
Automated tests catch bugs early and save time.
Testing API routes builds confidence in your backend code.
Practice
Solution
Step 1: Understand API route role
API routes handle backend logic and respond to client requests in Next.js.Step 2: Purpose of testing API routes
Testing ensures these routes respond correctly and handle inputs as expected.Final Answer:
To verify that the backend API responds correctly to requests -> Option AQuick Check:
API route testing = verify backend response [OK]
- Confusing API testing with frontend UI testing
- Thinking testing deploys the API
- Assuming API testing styles responses
Solution
Step 1: Identify default export usage
Next.js API routes usually export a default function as handler.Step 2: Correct import syntax for default export
Useimport handler from 'path'to import default export correctly.Final Answer:
import handler from '../pages/api/hello'; -> Option AQuick Check:
Default export import = import handler from [OK]
- Using require() in ES module context
- Trying to destructure default export
- Importing all as an object unnecessarily
res.status(200).json({ message: 'OK' })?
import handler from '../pages/api/hello';
import { createMocks } from 'node-mocks-http';
test('returns 200 status', async () => {
const { req, res } = createMocks({ method: 'GET' });
await handler(req, res);
expect(res._getStatusCode()).toBe(200);
});Solution
Step 1: Understand handler response
The handler sets status 200 and sends JSON with message 'OK'.Step 2: Test checks status code
The test expects status code 200, matching the handler's response.Final Answer:
200 -> Option BQuick Check:
Handler returns 200 status code [OK]
- Assuming default status is 404
- Confusing JSON response with status code
- Not awaiting async handler
import handler from '../pages/api/hello';
import { createMocks } from 'node-mocks-http';
test('returns 200 status', () => {
const { req, res } = createMocks({ method: 'GET' });
handler(req, res);
expect(res._getStatusCode()).toBe(200);
});Solution
Step 1: Check handler invocation
API route handlers are async functions and must be awaited in tests.Step 2: Identify missing async/await
The test function is not async and does not await handler, causing test to run before response is set.Final Answer:
Missing async/await for the handler call -> Option DQuick Check:
Async handler needs await in test [OK]
- Forgetting async keyword on test function
- Not awaiting the handler call
- Assuming synchronous execution
Solution
Step 1: Understand method-specific testing
Each HTTP method requires a separate mock request to simulate different behaviors.Step 2: Use separate mocks for GET and POST
CreateMocks should be called twice with method set to 'GET' and 'POST' respectively, calling handler each time.Final Answer:
Create separate tests using createMocks with method set to 'GET' and 'POST', then call handler for each -> Option CQuick Check:
Separate mocks per method = correct testing [OK]
- Reusing response object across methods
- Testing only one method and ignoring others
- Trying to combine methods in one mock
Ready to prove it?
Pass the test and this pattern moves unknown
