diff --git a/README.md b/README.md index 7f44aae..2636b6d 100644 --- a/README.md +++ b/README.md @@ -105,8 +105,8 @@ it('should handle expressjs requests', () => { ``` The expected type parameter in the mock request and response expects any type that extends the NodeJS -`http.IncomingRequest` interface. This means you can also mock requests coming from other frameworks -too. An example for NextJS request will look like this: +`http.IncomingRequest` interface or Fetch API `Request` class. This means you can also mock requests +coming from other frameworks too. An example for NextJS request will look like this: ```ts it('should handle nextjs requests', () => { @@ -123,6 +123,23 @@ it('should handle nextjs requests', () => { }); ``` +It is also possible to mock requests from the NextJS new AppRouter: + +```ts +it('should handle nextjs app reouter requests', () => { + const mockExpressRequest = httpMocks.createRequest<NextRequest>({ + method: 'GET', + url: '/user/42', + params: { + id: 42 + } + }); + const mockExpressResponse = httpMocks.createResponse<NextResponse>(); + + // ... the rest of the test as above. +}); +``` + ## API ### .createRequest() diff --git a/lib/http-mock.d.ts b/lib/http-mock.d.ts index c0eb3f1..b644c88 100644 --- a/lib/http-mock.d.ts +++ b/lib/http-mock.d.ts @@ -1,6 +1,9 @@ import { Request, Response, CookieOptions } from 'express'; import { IncomingMessage, OutgoingMessage } from 'http'; +export type RequestType = IncomingMessage | globalThis.Request; +export type ResponseType = OutgoingMessage | globalThis.Response; + export type RequestMethod = 'CONNECT' | 'DELETE' | 'GET' | 'HEAD' | 'OPTIONS' | 'PATCH' | 'POST' | 'PUT' | 'TRACE'; export interface Params { @@ -105,7 +108,7 @@ export interface RequestOptions { [key: string]: any; } -export type MockRequest<T extends IncomingMessage> = T & { +export type MockRequest<T extends RequestType> = T & { _setParameter: (key: string, value?: string) => void; _setSessionVariable: (variable: string, value?: string) => void; _setCookiesVariable: (variable: string, value?: string) => void; @@ -134,7 +137,7 @@ export type ResponseCookie = { options: CookieOptions; }; -export type MockResponse<T extends OutgoingMessage> = T & { +export type MockResponse<T extends ResponseType> = T & { _isEndCalled: () => boolean; _getHeaders: () => Headers; _getData: () => any; @@ -153,16 +156,16 @@ export type MockResponse<T extends OutgoingMessage> = T & { cookies: { [name: string]: ResponseCookie }; }; -export function createRequest<T extends IncomingMessage = Request>(options?: RequestOptions): MockRequest<T>; +export function createRequest<T extends RequestType = Request>(options?: RequestOptions): MockRequest<T>; -export function createResponse<T extends OutgoingMessage = Response>(options?: ResponseOptions): MockResponse<T>; +export function createResponse<T extends ResponseType = Response>(options?: ResponseOptions): MockResponse<T>; -export interface Mocks<T1 extends IncomingMessage, T2 extends OutgoingMessage> { +export interface Mocks<T1 extends RequestType, T2 extends ResponseType> { req: MockRequest<T1>; res: MockResponse<T2>; } -export function createMocks<T1 extends IncomingMessage = Request, T2 extends OutgoingMessage = Response>( +export function createMocks<T1 extends RequestType = Request, T2 extends ResponseType = Response>( reqOptions?: RequestOptions, resOptions?: ResponseOptions ): Mocks<T1, T2>; diff --git a/test/lib/http-mock.test-d.ts b/test/lib/http-mock.test-d.ts index 2934c95..ef38293 100644 --- a/test/lib/http-mock.test-d.ts +++ b/test/lib/http-mock.test-d.ts @@ -27,3 +27,5 @@ expectAssignable<NodeResponse>(createResponse<NodeResponse>()); expectNotAssignable<ExpressResponse>(createResponse<NodeResponse>()); expectType<Mocks<ExpressRequest, ExpressResponse>>(createMocks()); +// eslint-disable-next-line no-undef +expectType<Mocks<globalThis.Request, globalThis.Response>>(createMocks<globalThis.Request, globalThis.Response>()); diff --git a/test/lib/mockRequest.spec.ts b/test/lib/mockRequest.spec.ts index 32b58b8..d51834a 100644 --- a/test/lib/mockRequest.spec.ts +++ b/test/lib/mockRequest.spec.ts @@ -3,8 +3,8 @@ import * as url from 'url'; import * as querystring from 'querystring'; import parseRange from 'range-parser'; import { EventEmitter } from 'events'; - import { IncomingMessage } from 'http'; + import * as mockRequest from '../../lib/http-mock'; describe('mockRequest', () => { @@ -281,6 +281,11 @@ describe('mockRequest', () => { expect(request.ips).to.deep.equal([options.ip]); }); }); + + it('should be able to create a Fetch API Request object', () => { + const request = mockRequest.createRequest<Request>(); + expect(request.bodyUsed).to.be.undefined; + }); }); describe('.get()/.header()', () => { diff --git a/test/lib/mockResponse.spec.js b/test/lib/mockResponse.spec.js index 96a29fd..0af6482 100644 --- a/test/lib/mockResponse.spec.js +++ b/test/lib/mockResponse.spec.js @@ -1,14 +1,13 @@ const chai = require('chai'); - -const { expect } = chai; const sinon = require('sinon'); const sinonChai = require('sinon-chai'); -chai.use(sinonChai); - const mockResponse = require('../../lib/mockResponse'); const mockRequest = require('../../lib/mockRequest'); +const { expect } = chai; +chai.use(sinonChai); + describe('mockResponse', () => { it('should expose .createResponse()', () => { expect(mockResponse.createResponse).to.be.a('function');