diff --git a/CHANGELOG.md b/CHANGELOG.md index fe605049d..c21a48364 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,9 @@ - Features: - `winston` is now optional: supporting any logger having `debug()`, `warn()`, `info()` and `error()` methods; - Introducing module augmentation approach for setting the type of chosen logger; - - Supporting both `jest` and `vitest` frameworks for `testEndpoint()`. + - Supporting different testing frameworks for `testEndpoint()`: + - Both `jest` and `vitest` are supported automatically; + - With most modern Node.js you can also use the integrated `node:test` module. - How to migrate while maintaining previous functionality and behavior: - If you're going to continue using `winston`: - Near your `const config = createConfig(...)` add the module augmentation statement (see example below). @@ -28,7 +30,8 @@ - If you can not use `await` (on the top level of CommonJS): - Wrap your code with async IIFE or use `.then()` (see example below). - If you're using `testEndpoint()` method: - - Specify either `fnMethod: jest.fn` or `fnMethod: vi.fn` within its object argument. + - Add module augmentation statement once anywhere in your tests (see below); + - When using testing framework other than `jest` or `vitest`, specify `fnMethod` property to `testEndpoint()`. ```typescript import type { Logger } from "winston"; @@ -49,10 +52,19 @@ declare module "express-zod-api" { // (async () => { await ... })(); const { app, httpServer } = await createServer(config, routing); -// Adjust your tests: -const { responseMock } = await testEndpoint({ +// Adjust your tests: place it once anywhere +declare module "express-zod-api" { + interface MockOverrides extends jest.Mock {} // or Mock from vitest +} + +// Both jest and vitest are supported automatically +const { responseMock } = await testEndpoint({ endpoint }); + +// For other testing frameworks: specify fnMethod property +import { mock } from "node:test"; +await testEndpoint({ endpoint, - fnMethod: jest.fn, // or vi.fn from vitest, required + fnMethod: mock.fn.bind(mock), // https://nodejs.org/docs/latest-v20.x/api/test.html#mocking }); ``` diff --git a/README.md b/README.md index bf1adf3b5..55db18e63 100644 --- a/README.md +++ b/README.md @@ -1013,20 +1013,29 @@ const exampleEndpoint = taggedEndpointsFactory.build({ ## How to test endpoints The way to test endpoints is to mock the request, response, and logger objects, invoke the `execute()` method, and -assert the expectations for calls of certain mocked methods. The library provides a special method that makes mocking -easier, it requires either `jest` (with `@types/jest`) or `vitest` to be installed, so the test might look this way: +assert the expectations for calls of certain mocked methods. The library provides a special method `testEndpoint` that +makes mocking easier. It requires your either to install `jest` (with `@types/jest`) or `vitest` +(detects automatically), or to specify the `fnMethod` property assigned with a function mocking method of your testing +framework, which can also be `node:test` module of most modern Node.js versions. +However, in order to have proper mocking types in your own tests, you also need to specify `MockOverrides` once in your +tests excplicitly, so the tests should look this way: ```typescript import { testEndpoint } from "express-zod-api"; +// place it once anywhere in your tests +declare module "express-zod-api" { + interface MockOverrides extends jest.Mock {} // or Mock from vitest +} + test("should respond successfully", async () => { const { responseMock, loggerMock } = await testEndpoint({ - fnMethod: jest.fn, // or vi.fn from vitest endpoint: yourEndpoint, requestProps: { method: "POST", // default: GET body: {}, // incoming data as if after parsing (JSON) }, + // fnMethod — for testing frameworks other than jest or vitest // responseProps, configProps, loggerProps }); expect(loggerMock.error).toHaveBeenCalledTimes(0); diff --git a/example/example.swagger.yaml b/example/example.swagger.yaml index fd82cae7f..9523d77df 100644 --- a/example/example.swagger.yaml +++ b/example/example.swagger.yaml @@ -1,7 +1,7 @@ openapi: 3.0.0 info: title: Example API - version: 15.0.0-beta1 + version: 15.0.0-beta4 paths: /v1/user/retrieve: get: diff --git a/package.json b/package.json index 075909856..db54f141a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "express-zod-api", - "version": "15.0.0-beta1", + "version": "15.0.0-beta4", "description": "A Typescript library to help you get an API server up and running with I/O schema validation and custom middlewares in minutes.", "license": "MIT", "scripts": { diff --git a/src/common-helpers.ts b/src/common-helpers.ts index ce55adf0b..9c90c7b74 100644 --- a/src/common-helpers.ts +++ b/src/common-helpers.ts @@ -3,18 +3,14 @@ import { isHttpError } from "http-errors"; import { createHash } from "node:crypto"; import { z } from "zod"; import { CommonConfig, InputSource, InputSources } from "./config-type"; -import { - InputValidationError, - MissingPeerError, - OutputValidationError, -} from "./errors"; +import { InputValidationError, OutputValidationError } from "./errors"; import { ZodFile } from "./file-schema"; import { IOSchema } from "./io-schema"; +import { AbstractLogger } from "./logger"; import { getMeta } from "./metadata"; import { AuxMethod, Method } from "./method"; import { mimeMultipart } from "./mime"; import { ZodUpload } from "./upload-schema"; -import { AbstractLogger } from "./logger"; export type FlatObject = Record; @@ -323,14 +319,3 @@ export type ErrMessage = Exclude< // the copy of the private Zod errorUtil.errToObj export const errToObj = (message: ErrMessage | undefined) => typeof message === "string" ? { message } : message || {}; - -export const loadPeer = async ( - moduleName: string, - moduleExport: string = "default", -): Promise => { - try { - return (await import(moduleName))[moduleExport]; - } catch { - throw new MissingPeerError(moduleName); - } -}; diff --git a/src/errors.ts b/src/errors.ts index 88429cdcd..71eab34d6 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -69,9 +69,14 @@ export class ResultHandlerError extends Error { export class MissingPeerError extends Error { public override name = "MissingPeerError"; - constructor(module: string) { + constructor(module: string | string[]) { + const isArray = Array.isArray(module); super( - `Missing peer dependency: '${module}'. Please install it to use the feature activated in config.`, + `Missing ${ + isArray ? "one of the following peer dependencies" : "peer dependency" + }: ${ + isArray ? module.join(" | ") : module + }. Please install it to use the feature.`, ); } } diff --git a/src/index.ts b/src/index.ts index 9de15901c..41e8113d9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -33,7 +33,7 @@ export { MissingPeerError, } from "./errors"; export { withMeta } from "./metadata"; -export { testEndpoint } from "./testing"; +export { testEndpoint, MockOverrides } from "./testing"; export { Integration } from "./integration"; export * as ez from "./proprietary-schemas"; diff --git a/src/logger.ts b/src/logger.ts index efe88aa61..b0587983b 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -2,7 +2,7 @@ import { inspect } from "node:util"; import type { Format, TransformableInfo } from "logform"; import type Winston from "winston"; import type Transport from "winston-transport"; -import { loadPeer } from "./common-helpers"; +import { loadPeer } from "./peer-helpers"; /** * @desc Using module augmentation approach you can set the type of the actual logger used diff --git a/src/peer-helpers.ts b/src/peer-helpers.ts new file mode 100644 index 000000000..7e61a2230 --- /dev/null +++ b/src/peer-helpers.ts @@ -0,0 +1,35 @@ +import { MissingPeerError } from "./errors"; + +export const loadPeer = async ( + moduleName: string, + moduleExport: string = "default", +): Promise => { + try { + return (await import(moduleName))[moduleExport]; + } catch {} + try { + return await Promise.resolve().then( + /** + * alternative way for environments that do not support dynamic imports even it's CJS compatible + * @example jest with ts-jest + * @link https://github.com/evanw/esbuild/issues/2651 + */ + () => require(moduleName)[moduleExport], + ); + } catch {} + throw new MissingPeerError(moduleName); +}; + +export const loadAlternativePeer = async ( + options: { + moduleName: string; + moduleExport?: string; + }[], +) => { + for (const { moduleName, moduleExport } of options) { + try { + return await loadPeer(moduleName, moduleExport); + } catch {} + } + throw new MissingPeerError(options.map(({ moduleName }) => moduleName)); +}; diff --git a/src/server.ts b/src/server.ts index ac9f3f59e..5bee96a90 100644 --- a/src/server.ts +++ b/src/server.ts @@ -10,7 +10,8 @@ import { isSimplifiedWinstonConfig, } from "./logger"; import { ResultHandlerError } from "./errors"; -import { loadPeer, makeErrorFromAnything } from "./common-helpers"; +import { makeErrorFromAnything } from "./common-helpers"; +import { loadPeer } from "./peer-helpers"; import { AnyResultHandlerDefinition, defaultResultHandler, diff --git a/src/testing.ts b/src/testing.ts index 3b7b11a10..54e8c364e 100644 --- a/src/testing.ts +++ b/src/testing.ts @@ -4,33 +4,32 @@ import { CommonConfig } from "./config-type"; import { AbstractEndpoint } from "./endpoint"; import { AbstractLogger } from "./logger"; import { mimeJson } from "./mime"; +import { loadAlternativePeer } from "./peer-helpers"; -type MockFunction = (implementation?: (...args: any[]) => any) => S; // kept "any" for easier compatibility +export interface MockOverrides {} -export const makeRequestMock = < - REQ extends Record, - FN extends MockFunction, ->({ +interface MockFunction { + (implementation?: (...args: any[]) => any): MockOverrides; +} + +export const makeRequestMock = >({ fnMethod, requestProps, }: { - fnMethod: FN; + fnMethod: MockFunction; requestProps?: REQ; }) => ({ method: "GET", header: fnMethod(() => mimeJson), ...requestProps, - }) as { method: string } & Record<"header", ReturnType> & REQ; + }) as { method: string } & Record<"header", MockOverrides> & REQ; -export const makeResponseMock = < - RES extends Record, - FN extends MockFunction, ->({ +export const makeResponseMock = >({ fnMethod, responseProps, }: { - fnMethod: FN; + fnMethod: MockFunction; responseProps?: RES; }) => { const responseMock = { @@ -58,13 +57,13 @@ export const makeResponseMock = < statusMessage: string; } & Record< "set" | "setHeader" | "header" | "status" | "json" | "send" | "end", - ReturnType + MockOverrides > & RES; return responseMock; }; -interface TestEndpointProps { +interface TestEndpointProps { /** @desc The endpoint to test */ endpoint: AbstractEndpoint; /** @@ -88,19 +87,15 @@ interface TestEndpointProps { * */ loggerProps?: LOG; /** - * @example jest.fn - * @example vi.fn + * @desc Optionally specify the function mocking method of your testing framework + * @default jest.fn || vi.fn // from vitest + * @example mock.fn.bind(mock) // from node:test, binding might be necessary * */ - fnMethod: FN; + fnMethod?: MockFunction; } -/** - * @desc You need to install either jest (with @types/jest) or vitest in order to use this method - * @requires jest - * @requires vitest - * */ +/** @desc Requires either jest (with @types/jest) or vitest or to specify the fnMethod option */ export const testEndpoint = async < - FN extends MockFunction, LOG extends Record, REQ extends Record, RES extends Record, @@ -110,8 +105,16 @@ export const testEndpoint = async < responseProps, configProps, loggerProps, - fnMethod, -}: TestEndpointProps) => { + fnMethod: userDefined, +}: TestEndpointProps) => { + const fnMethod = + userDefined || + ( + await loadAlternativePeer<{ fn: MockFunction }>([ + { moduleName: "vitest", moduleExport: "vi" }, + { moduleName: "@jest/globals", moduleExport: "jest" }, + ]) + ).fn; const requestMock = makeRequestMock({ fnMethod: fnMethod, requestProps }); const responseMock = makeResponseMock({ fnMethod: fnMethod, responseProps }); const loggerMock = { @@ -120,7 +123,7 @@ export const testEndpoint = async < error: fnMethod(), debug: fnMethod(), ...loggerProps, - } as Record> & LOG; + } as Record & LOG; const configMock = { cors: false, logger: loggerMock, @@ -130,7 +133,7 @@ export const testEndpoint = async < request: requestMock as unknown as Request, response: responseMock as unknown as Response, config: configMock as CommonConfig, - logger: loggerMock as AbstractLogger, + logger: loggerMock as unknown as AbstractLogger, }); return { requestMock, responseMock, loggerMock }; }; diff --git a/tests/unit/__snapshots__/index.spec.ts.snap b/tests/unit/__snapshots__/index.spec.ts.snap index 46d0e4076..3750fc01c 100644 --- a/tests/unit/__snapshots__/index.spec.ts.snap +++ b/tests/unit/__snapshots__/index.spec.ts.snap @@ -102,6 +102,7 @@ exports[`Index Entrypoint exports should have certain entities exposed 1`] = ` "LoggerOverrides", "Method", "MissingPeerError", + "MockOverrides", "OutputValidationError", "Routing", "RoutingError", diff --git a/tests/unit/common-helpers.spec.ts b/tests/unit/common-helpers.spec.ts index aa13c74ab..3f74cf413 100644 --- a/tests/unit/common-helpers.spec.ts +++ b/tests/unit/common-helpers.spec.ts @@ -14,15 +14,9 @@ import { hasTopLevelTransformingEffect, isCustomHeader, isValidDate, - loadPeer, makeErrorFromAnything, } from "../../src/common-helpers"; -import { - InputValidationError, - MissingPeerError, - ez, - withMeta, -} from "../../src"; +import { InputValidationError, ez, withMeta } from "../../src"; import { Request } from "express"; import { z } from "zod"; import { ZodUpload } from "../../src/upload-schema"; @@ -512,15 +506,4 @@ describe("Common Helpers", () => { }, ); }); - - describe("loadPeer()", () => { - test("should load the module", async () => { - expect(await loadPeer("compression")).toBeTruthy(); - }); - test("should throw when module not found", async () => { - await expect(async () => loadPeer("missing")).rejects.toThrow( - new MissingPeerError("missing"), - ); - }); - }); }); diff --git a/tests/unit/endpoint.spec.ts b/tests/unit/endpoint.spec.ts index f909e2c1d..a85f37aeb 100644 --- a/tests/unit/endpoint.spec.ts +++ b/tests/unit/endpoint.spec.ts @@ -88,7 +88,6 @@ describe("Endpoint", () => { }); const { requestMock, responseMock, loggerMock } = await testEndpoint({ endpoint, - fnMethod: jest.fn, requestProps: { method: "POST", body: { n: 453 }, @@ -131,7 +130,6 @@ describe("Endpoint", () => { handler: handlerMock, }); const { responseMock, loggerMock } = await testEndpoint({ - fnMethod: jest.fn, endpoint, requestProps: { method: "OPTIONS", @@ -176,10 +174,7 @@ describe("Endpoint", () => { output: z.object({ email: z.string().email() }), handler: async () => ({ email: "not email" }), }); - const { responseMock } = await testEndpoint({ - endpoint, - fnMethod: jest.fn, - }); + const { responseMock } = await testEndpoint({ endpoint }); expect(responseMock.status).toHaveBeenCalledWith(500); expect(responseMock.json).toHaveBeenCalledWith({ status: "error", @@ -203,10 +198,7 @@ describe("Endpoint", () => { test: 123, }), }); - const { responseMock, loggerMock } = await testEndpoint({ - endpoint, - fnMethod: jest.fn, - }); + const { responseMock, loggerMock } = await testEndpoint({ endpoint }); expect(loggerMock.error).toHaveBeenCalledTimes(1); expect(responseMock.status).toHaveBeenCalledWith(500); expect(responseMock.json).toHaveBeenCalledWith({ @@ -243,7 +235,6 @@ describe("Endpoint", () => { handler: handlerMock, }); const { responseMock, loggerMock } = await testEndpoint({ - fnMethod: jest.fn, endpoint, requestProps: { method: "POST", @@ -284,10 +275,7 @@ describe("Endpoint", () => { }), handler: async () => ({ test: "OK" }), }); - const { loggerMock, responseMock } = await testEndpoint({ - endpoint, - fnMethod: jest.fn, - }); + const { loggerMock, responseMock } = await testEndpoint({ endpoint }); expect(loggerMock.error).toHaveBeenCalledTimes(1); expect(loggerMock.error.mock.calls[0][0]).toBe( "Result handler failure: Something unexpected happened.", @@ -435,7 +423,6 @@ describe("Endpoint", () => { }); const { responseMock } = await testEndpoint({ endpoint, - fnMethod: jest.fn, requestProps: { method: "POST", body: { n: 123, m: 5 }, @@ -479,7 +466,6 @@ describe("Endpoint", () => { }); const { responseMock } = await testEndpoint({ endpoint, - fnMethod: jest.fn, requestProps: { method: "OPTIONS", }, @@ -506,10 +492,7 @@ describe("Endpoint", () => { test: 123, }), }); - const { responseMock, loggerMock } = await testEndpoint({ - endpoint, - fnMethod: jest.fn, - }); + const { responseMock, loggerMock } = await testEndpoint({ endpoint }); expect(loggerMock.error).toHaveBeenCalledTimes(1); expect(responseMock.status).toHaveBeenCalledWith(500); expect(responseMock.json).toHaveBeenCalledWith({ @@ -539,10 +522,7 @@ describe("Endpoint", () => { }), handler: async () => ({ test: "OK" }), }); - const { loggerMock, responseMock } = await testEndpoint({ - endpoint, - fnMethod: jest.fn, - }); + const { loggerMock, responseMock } = await testEndpoint({ endpoint }); expect(loggerMock.error).toHaveBeenCalledTimes(1); expect(loggerMock.error.mock.calls[0][0]).toBe( "Result handler failure: Something unexpected happened.", @@ -574,7 +554,6 @@ describe("Endpoint", () => { }); const { responseMock, loggerMock } = await testEndpoint({ endpoint, - fnMethod: jest.fn, requestProps: { method: "POST", body: {}, @@ -628,7 +607,6 @@ describe("Endpoint", () => { test("should accept valid inputs", async () => { const { responseMock } = await testEndpoint({ endpoint, - fnMethod: jest.fn, requestProps: { method: "POST", body: { @@ -647,7 +625,6 @@ describe("Endpoint", () => { test("should fail during the refinement of invalid inputs", async () => { const { responseMock } = await testEndpoint({ endpoint, - fnMethod: jest.fn, requestProps: { method: "POST", body: { @@ -668,7 +645,6 @@ describe("Endpoint", () => { test("should refine the output schema as well", async () => { const { responseMock } = await testEndpoint({ endpoint, - fnMethod: jest.fn, requestProps: { method: "POST", body: { @@ -708,7 +684,6 @@ describe("Endpoint", () => { test("should accept valid inputs", async () => { const { responseMock } = await testEndpoint({ endpoint, - fnMethod: jest.fn, requestProps: { method: "POST", body: { @@ -726,7 +701,6 @@ describe("Endpoint", () => { test("should fail during the refinement of invalid inputs", async () => { const { responseMock } = await testEndpoint({ endpoint, - fnMethod: jest.fn, requestProps: { method: "POST", body: {}, @@ -810,7 +784,6 @@ describe("Endpoint", () => { const { loggerMock, responseMock } = await testEndpoint({ endpoint, - fnMethod: jest.fn, requestProps: { query: { middleware_date_input: "2022-09-28", diff --git a/tests/unit/errors.spec.ts b/tests/unit/errors.spec.ts index bc70aae86..7281ffcc8 100644 --- a/tests/unit/errors.spec.ts +++ b/tests/unit/errors.spec.ts @@ -120,7 +120,10 @@ describe("Errors", () => { test("should have a human readable message", () => { expect(new MissingPeerError("compression").message).toBe( - "Missing peer dependency: 'compression'. Please install it to use the feature activated in config.", + "Missing peer dependency: compression. Please install it to use the feature.", + ); + expect(new MissingPeerError(["jest", "vitest"]).message).toBe( + "Missing one of the following peer dependencies: jest | vitest. Please install it to use the feature.", ); }); }); diff --git a/tests/unit/peer-helpers.spec.ts b/tests/unit/peer-helpers.spec.ts new file mode 100644 index 000000000..1ddd6e3b4 --- /dev/null +++ b/tests/unit/peer-helpers.spec.ts @@ -0,0 +1,34 @@ +import { MissingPeerError } from "../../src"; +import { loadAlternativePeer, loadPeer } from "../../src/peer-helpers"; + +describe("Peer loading helpers", () => { + describe("loadPeer()", () => { + test("should load the module", async () => { + expect(await loadPeer("compression")).toBeTruthy(); + }); + test("should throw when module not found", async () => { + await expect(async () => loadPeer("missing")).rejects.toThrow( + new MissingPeerError("missing"), + ); + }); + }); + + describe("loadAltPeer()", () => { + test("should load an alternative module", async () => { + expect( + await loadAlternativePeer([ + { moduleName: "vitest", moduleExport: "vi" }, + { moduleName: "@jest/globals", moduleExport: "jest" }, + ]), + ).toBeTruthy(); + }); + test("should throw when no alternatives found", async () => { + await expect(async () => + loadAlternativePeer([ + { moduleName: "vitest" }, + { moduleName: "@also/missing" }, + ]), + ).rejects.toThrow(new MissingPeerError(["vitest", "@also/missing"])); + }); + }); +}); diff --git a/tests/unit/testing.spec.ts b/tests/unit/testing.spec.ts index d2d95416d..f284677f1 100644 --- a/tests/unit/testing.spec.ts +++ b/tests/unit/testing.spec.ts @@ -1,3 +1,4 @@ +import { expectType } from "tsd"; import { z } from "zod"; import { createMiddleware, @@ -5,49 +6,59 @@ import { testEndpoint, } from "../../src"; +declare module "../../src" { + interface MockOverrides extends jest.Mock {} +} + describe("Testing", () => { describe("testEndpoint()", () => { - test("Should test the endpoint", async () => { - const endpoint = defaultEndpointsFactory - .addMiddleware( - createMiddleware({ + test.each([undefined, jest.fn])( + "Should test the endpoint %#", + async (fnMethod) => { + const endpoint = defaultEndpointsFactory + .addMiddleware( + createMiddleware({ + input: z.object({}), + middleware: async ({ response }) => { + response + .setHeader("X-Some", "header") + .header("X-Another", "header as well") + .send("this is just for testing mocked methods"); + return {}; + }, + }), + ) + .build({ + method: "get", input: z.object({}), - middleware: async ({ response }) => { - response - .setHeader("X-Some", "header") - .header("X-Another", "header as well") - .send("this is just for testing mocked methods"); - return {}; - }, - }), - ) - .build({ - method: "get", - input: z.object({}), - output: z.object({}), - handler: async () => ({}), + output: z.object({}), + handler: async () => ({}), + }); + const { responseMock, requestMock, loggerMock } = await testEndpoint({ + endpoint, + responseProps: { prop1: jest.fn(), prop2: 123 }, + requestProps: { test1: jest.fn(), test2: 456 }, + loggerProps: { feat1: jest.fn(), feat2: 789 }, + fnMethod, }); - const { responseMock, requestMock, loggerMock } = await testEndpoint({ - endpoint, - fnMethod: jest.fn, - responseProps: { prop1: jest.fn(), prop2: 123 }, - requestProps: { test1: jest.fn(), test2: 456 }, - loggerProps: { feat1: jest.fn(), feat2: 789 }, - }); - expect(responseMock.setHeader).toHaveBeenCalledWith("X-Some", "header"); - expect(responseMock.header).toHaveBeenCalledWith( - "X-Another", - "header as well", - ); - expect(responseMock.send).toHaveBeenCalledWith( - "this is just for testing mocked methods", - ); - expect(responseMock.prop1).toEqual(expect.any(Function)); - expect(responseMock.prop2).toBe(123); - expect(requestMock.test1).toEqual(expect.any(Function)); - expect(requestMock.test2).toBe(456); - expect(loggerMock.feat1).toEqual(expect.any(Function)); - expect(loggerMock.feat2).toBe(789); - }); + expect(responseMock.setHeader).toHaveBeenCalledWith("X-Some", "header"); + expect(responseMock.header).toHaveBeenCalledWith( + "X-Another", + "header as well", + ); + expect(responseMock.send).toHaveBeenCalledWith( + "this is just for testing mocked methods", + ); + expect(responseMock.prop1).toEqual(expect.any(Function)); + expect(responseMock.prop2).toBe(123); + expect(requestMock.test1).toEqual(expect.any(Function)); + expect(requestMock.test2).toBe(456); + expect(loggerMock.feat1).toEqual(expect.any(Function)); + expect(loggerMock.feat2).toBe(789); + expectType(responseMock.prop1); + expectType(requestMock.test1); + expectType(loggerMock.feat1); + }, + ); }); }); diff --git a/tests/vitest/compat.spec.ts b/tests/vitest/compat.spec.ts index 20a50dccf..e5413084b 100644 --- a/tests/vitest/compat.spec.ts +++ b/tests/vitest/compat.spec.ts @@ -1,8 +1,12 @@ import { defaultEndpointsFactory } from "../../src"; -import { describe, expect, test, vi } from "vitest"; +import { Mock, describe, expect, test } from "vitest"; import { z } from "zod"; import { testEndpoint } from "../../src"; +declare module "../../src" { + interface MockOverrides extends Mock {} +} + describe("Vitest compatibility test", () => { describe("testEndpoint()", () => { test("should support vi.fn", async () => { @@ -14,7 +18,6 @@ describe("Vitest compatibility test", () => { }); const { responseMock } = await testEndpoint({ endpoint, - fnMethod: vi.fn, requestProps: { method: "POST", body: { n: 123 } }, }); expect(responseMock.status).toHaveBeenCalledWith(200);