Created
October 27, 2023 08:00
-
-
Save mustafadalga/5d8e8d0a987a459ffb5c5a0b41c3c070 to your computer and use it in GitHub Desktop.
Demonstration of unit testing for Next.js 13 API routes, covering GET and POST methods using mocks with msw.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { describe, it, expect, beforeAll, afterEach, afterAll } from "vitest"; | |
import { GET } from "./route"; | |
import { createMockRequest, createTestServer } from "@/__tests__/utilities"; | |
import { http, HttpResponse } from "msw"; | |
const url = `${process.env.VITE_API_BASE_URL_V2}/posts`; | |
const mockPosts = [ { | |
"userId": 1, | |
"id": 2, | |
"title": "qui est esse", | |
"body": "est rerum tempore vitaeequi sint nihil reprehenderit dolor beatae ea dolores nequeugiat blanditiis voluptate porro vel nihil molestiae ut reiciendisqui aperiam non debitis possimus qui neque nisi nulla" | |
} ] | |
const server = createTestServer({ | |
url, | |
successResponse: mockPosts, | |
method: "GET" | |
}); | |
beforeAll(() => server.listen()); | |
afterEach(() => server.resetHandlers()); | |
afterAll(() => server.close()); | |
describe("Clients API Route", () => { | |
const request = createMockRequest({ method: "GET" }); | |
it("should return a list of client", async () => { | |
const response = await GET(request); | |
const responseJson = await response.json(); | |
expect(responseJson).toEqual(mockPosts); | |
expect(response.status).toBe(200); | |
}) | |
it("should return an error message when the API call fails", async () => { | |
const message = "Interval Error" | |
server.use( | |
http.get(url, () => { | |
return HttpResponse.json({ | |
message | |
}, { status: 500 }) | |
}), | |
); | |
const response = await GET(request); | |
const responseJson = await response.json(); | |
expect(responseJson.message).toEqual(message); | |
expect(response.status).not.toBe(200); | |
}) | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { NextRequest, NextResponse } from "next/server"; | |
import { AxiosInstance } from "axios"; | |
import { CookieKeys } from "@/_enums"; | |
import createAuthenticatedApiServiceV2 from "@/_services/createAuthenticatedApiServiceV2"; | |
import handleAxiosError from "@/_utilities/handleAxiosError"; | |
export async function GET(request: NextRequest) { | |
const jwt: string | undefined = request.cookies.get(CookieKeys.Jwt)?.value; | |
const api: AxiosInstance = createAuthenticatedApiServiceV2(jwt); | |
if (request.method !== "GET") { | |
return NextResponse.json({ message: "Method not allowed" }, { status: 405 }) | |
} | |
try { | |
const { data } = await api.get("/posts"); | |
return NextResponse.json(data, { status: 200 }); | |
} catch (error) { | |
const { | |
message, | |
status, | |
details | |
} = handleAxiosError(error, "Oops! Something went wrong while loading posts. Please refresh the page and try again!"); | |
return NextResponse.json({ message, details }, { status }); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { it, describe, expect, beforeAll, afterEach, afterAll } from "vitest"; | |
import { POST } from "./route"; | |
import { createMockRequest, createTestServer } from "@/__tests__/utilities"; | |
import { http, HttpResponse } from "msw"; | |
const url = `${process.env.VITE_API_BASE_URL_V2}/post/create`; | |
const successResponse = { | |
message: "The post has been created successfully." | |
} | |
const server = createTestServer({ | |
url, | |
successResponse, | |
method: "POST" | |
}); | |
beforeAll(() => server.listen()); | |
afterEach(() => server.resetHandlers()); | |
afterAll(() => server.close()); | |
describe("Create Anomaly API Route", () => { | |
const mockPost = { | |
"userId": 1, | |
"id": 2, | |
"title": "qui est esse", | |
"body": "est rerum tempore vitaeequi sint nihil reprehenderit dolor beatae ea dolores nequeugiat blanditiis voluptate porro vel nihil molestiae ut reiciendisqui aperiam non debitis possimus qui neque nisi nulla" | |
} | |
const request = createMockRequest({ data: mockPost, method: "POST" }); | |
it('should create post', async () => { | |
const response = await POST(request); | |
const responseJson = await response.json(); | |
expect(responseJson.message).toBe(successResponse.message); | |
expect(response.status).toBe(200); | |
}); | |
it("should return an error message when the API call fails", async () => { | |
const message = "Oops! Something went wrong While creating post!"; | |
server.use( | |
http.post(url, () => { | |
return HttpResponse.json({ | |
message, | |
}, { status: 500 }) | |
}), | |
); | |
const response = await POST(request); | |
const responseJson = await response.json(); | |
expect(responseJson.message).toBe(message); | |
expect(response.status).toBe(500); | |
}); | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { NextRequest, NextResponse } from "next/server"; | |
import { AxiosInstance } from "axios"; | |
import { CookieKeys } from "@/_enums"; | |
import createAuthenticatedApiServiceV2 from "@/_services/createAuthenticatedApiServiceV2"; | |
import handleAxiosError from "@/_utilities/handleAxiosError"; | |
export async function POST(request: NextRequest) { | |
const jwt: string | undefined = request.cookies.get(CookieKeys.Jwt)?.value; | |
const api: AxiosInstance = createAuthenticatedApiServiceV2(jwt); | |
if (request.method !== "POST") { | |
return NextResponse.json({ message: "Method not allowed" }, { status: 405 }) | |
} | |
try { | |
const body = await request.json(); | |
const { data } = await api.post("/post/create", { | |
data: body | |
}); | |
return NextResponse.json(data, { status: 200 }); | |
} catch (error) { | |
const { | |
message, | |
status, | |
details | |
} = handleAxiosError(error, "Oops! Something went wrong while creating post. Please refresh the page and try again!"); | |
return NextResponse.json({ message, details }, { status }); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment