Testing
Typeweaver projects are usually easiest to test in layers. You do not need special public Typeweaver testing packages for that. Your normal test framework is enough.
What to test
The most useful tests usually cover four things:
- spec-level expectations for important contract shapes
- generated validators for request and response boundaries
- generated clients for request and response behavior
- handlers for business logic and returned responses
Test validators directly
Validators are great small tests because they prove the contract still accepts and rejects what you expect.
Vitest example
import { describe, expect, it } from "vitest";
import { GetTodoRequestValidator } from "../api/generated";
import { HttpMethod } from "@rexeus/typeweaver-core";
describe("GetTodoRequestValidator", () => {
it("accepts a valid request", () => {
const validator = new GetTodoRequestValidator();
const result = validator.safeValidate({
method: HttpMethod.GET,
path: "/todos/todo_123",
param: {
todoId: "todo_123",
},
});
expect(result.isValid).toBe(true);
});
it("rejects a request with missing params", () => {
const validator = new GetTodoRequestValidator();
const result = validator.safeValidate({
method: HttpMethod.GET,
path: "/todos",
param: {},
});
expect(result.isValid).toBe(false);
});
});
Use the same idea in Jest if that is what your project already uses.
Test generated clients with a mocked fetch
Generated clients are easiest to test by mocking the transport and asserting on the typed response.
import { expect, it, vi } from "vitest";
import { GetTodoRequestCommand, TodoClient } from "../api/generated";
it("returns a typed success response", async () => {
const fetchFn = vi.fn().mockResolvedValue(
new Response(
JSON.stringify({
id: "todo_123",
title: "Ship docs",
completed: false,
}),
{
status: 200,
headers: {
"Content-Type": "application/json",
},
}
)
);
const client = new TodoClient({
baseUrl: "https://api.example.com",
fetchFn,
});
const response = await client.send(
new GetTodoRequestCommand({
param: {
todoId: "todo_123",
},
})
);
expect(response.type).toBe("GetTodoSuccess");
});
This catches contract mismatches without needing a real server.
Test handlers as normal application code
Handlers are just functions with typed input and typed responses. Test them the same way you would test any business logic.
import { expect, it } from "vitest";
import { createGetTodoSuccessResponse } from "../api/generated";
const handleGetTodoRequest = async ({
param,
}: {
param: { todoId: string };
}) => {
return createGetTodoSuccessResponse({
body: {
id: param.todoId,
title: "Ship docs",
completed: false,
},
});
};
it("returns the todo when it exists", async () => {
const response = await handleGetTodoRequest({
param: {
todoId: "todo_123",
},
});
expect(response).toEqual(
createGetTodoSuccessResponse({
body: {
id: "todo_123",
title: "Ship docs",
completed: false,
},
})
);
});
Keep testing practical
You usually do not need a separate test for every generated type. Focus on the places where drift would hurt:
- required request fields
- important response branches
- client handling of normal success and error responses
- handler behavior for your main business cases