Testing API Routes
#2942
-
I spent couple of hours figuring out how to test API routes until I found out https://github.com/ljosberinn/personal-react-boilerplate/blob/master/testUtils/api.ts. I think it would be nice if:
Example:
import { BlitzApiHandler } from "blitz"
const handler: BlitzApiHandler = async (req, res) => {
res.status(200).json({ name: "John Doe" })
}
export default handler
import { createApiRequestMock, createApiResponseMock } from "test/api/utils"
import handler from "./hello"
test("returns JSON", async () => {
const req = createApiRequestMock({ method: "GET" })
const res = createApiResponseMock({
status: jest.fn().mockReturnThis(),
json: jest.fn(),
})
await handler(req, res)
expect(res.json).toHaveBeenCalledWith({
name: "John Doe",
})
expect(res.status).toHaveBeenCalledWith(200)
})
import { IncomingMessage, ServerResponse } from "http"
import { Socket } from "net"
import type { BlitzApiRequest, BlitzApiResponse } from "next"
export class BlitzApiResponseMock extends ServerResponse implements BlitzApiResponse {
public send = jest.fn()
public json = jest.fn()
public redirect = jest.fn()
public setPreviewData = jest.fn()
public clearPreviewData = jest.fn()
public status(code: number): this {
this.statusCode = code
return this
}
}
export class BlitzApiRequestMock extends IncomingMessage implements BlitzApiRequest {
public body = {}
public env = {}
public query = {}
public cookies = {}
public req = createIncomingMessageMock()
public constructor(req: IncomingMessage) {
super(req.socket)
}
}
export const createApiRequestMock = (req: Partial<BlitzApiRequest> = {}): BlitzApiRequest => {
const request = new BlitzApiRequestMock(createIncomingMessageMock(req))
Object.entries(req).forEach(([key, value]) => {
Object.defineProperty(request, key, { value })
})
return request
}
export const createIncomingMessageMock = (req: Partial<IncomingMessage> = {}): IncomingMessage => {
const request = new IncomingMessage(new Socket())
Object.entries(req).forEach(([key, value]) => {
Object.defineProperty(request, key, { value })
})
return request
}
export const createApiResponseMock = (res: Partial<BlitzApiResponse> = {}): BlitzApiResponse => {
const apiResponseMock = new BlitzApiResponseMock(new IncomingMessage(new Socket()))
Object.entries(res).forEach(([key, value]) => {
Object.defineProperty(apiResponseMock, key, { value })
})
return apiResponseMock
} |
Beta Was this translation helpful? Give feedback.
Answered by
beerose
Nov 12, 2021
Replies: 1 comment
-
Hey @ebeigarts! Thanks for this and thanks for describing the APIs! It looks good — could you open a PR for that? One thing we could change is removing the
If you need any help, let us know! |
Beta Was this translation helpful? Give feedback.
0 replies
Answer selected by
beerose
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hey @ebeigarts! Thanks for this and thanks for describing the APIs! It looks good — could you open a PR for that?
One thing we could change is removing the
Api
from the name:createApiResponseMock
->createResponseMock
.Things to do:
nextjs/packages/next/test-utils/index.ts
.test-utils
to thenext
package: https://github.com/blitz-js/blitz/blob/canary/nextjs/packages/next/ (You can take a look atstdlib
as an example).test-utils.js
file with export.test-utils.d.ts
file with declaration exports.package.json
to thefiles
array.test-utils
to taskfile.js — you can find mentions ofstdlib
an…