amber.srivastava
Thu Sep 26 2024
How to test an API endpoint.
Lets say we have to test an API endpoint api/projects
describe("POST /api/projects", () => {
test("redirect with 401 status if the user is not logged in", async () => {
jest
.spyOn(nextAuth, "getServerSession")
.mockImplementation(() => Promise.resolve());
const req = createRequest<APIRequest>({
method: "POST",
url: "/api/projects",
body: projectData,
});
const res = await postProjectHandler(req as any);
expect(res.status).toEqual(401);
});
test("return 400 if the request body is invalid", async () => {
jest.spyOn(nextAuth, "getServerSession").mockImplementation(() =>
Promise.resolve({
user: {
id: user.id,
},
})
);
const req = createRequest<APIRequest>({
method: "POST",
url: "/api/projects",
body: {},
});
req.json = jest.fn().mockResolvedValue(req.body);
const res = await postProjectHandler(req as any);
expect(res.status).toEqual(400);
});
test("store project in database", async () => {
jest.spyOn(nextAuth, "getServerSession").mockImplementation(() =>
Promise.resolve({
user: {
id: user.id,
},
})
);
const mockResponse = {
ok: true,
team: {
id: "T08DABCD",
name: "Prisma",
},
};
const mockList = jest.fn().mockResolvedValue(mockResponse);
<http://slackClient.team.info|slackClient.team.info> = mockList;
const req = createRequest<APIRequest>({
method: "POST",
url: "/api/projects",
body: {
...projectData,
},
});
req.json = jest.fn().mockResolvedValue(req.body);
const res = await postProjectHandler(req as any);
const json = await res.json();
expect(res.status).toEqual(201);
expect(json.project.name).toEqual("Test name");
expect(json.project.description).toEqual(
"Test description"
);
});
});
describe
: This is a block in Jest used to group related tests together. In our case, it groups tests for thePOST /api/projects
endpoint. It helps organize tests logically.test
: Eachtest
block defines an individual test case. It contains a name (description) of what it’s testing and a function with the test logic. The three tests are: • User is redirected with a401
if they are not logged in. • A400
status is returned if the request body is invalid. • The project is stored in the database when valid data is provided.- Mocking:
•
jest.spyOn()
: This creates a mock (or "spy") for a specific function. In this case, we are mocking thegetServerSession
function fromnextAuth
to control its output (whether the user is logged in or not). This avoids actually calling the real function and allows you to simulate different conditions. • Mock Implementation: With.mockImplementation()
, we’re replacing the real function with a custom one. For example, in the first test,Promise.resolve()
is returned to simulate a missing session (not logged in). createRequest<APIRequest>()
: This is likely a helper function that creates a mock request object for testing. We use this to simulate an HTTP request (like sending a POST request to your/api/projects
endpoint). It includes: •method
: Specifies that it’s a POST request. •url
: The endpoint being tested. •body
: The request data sent with the POST request.postProjectHandler(req as any)
: This function is our handler for thePOST /api/projects
endpoint. It processes the incoming request (inreq
), validates the data, and performs actions like saving to the database or returning errors. We’re testing the results of this function.- Assertions:
•
expect(res.status).toEqual(401)
: This is checking if the response status matches the expected value. For example, in the first test, we expect a401
status if the user isn’t logged in. •expect(json.project.name).toEqual("Test name")
: Here, you're checking if the response JSON contains the correct project name. <#CCT1JMA0Z|> #promises <#C041BBLJ57G|> #jest #appRouter