How to Test TRPC
I am trying to setup testing TRPC
My Init looks like this:
My test looks like this
All I really need in the context to test with is
import { initTRPC, TRPCError } from "@trpc/server";
import superjson from "superjson";
import { ZodError } from "zod";
import { auth, clerkClient } from "@clerk/nextjs/server";
// export const createTRPCContext = async (opts: { headers: Headers }) => {
export const createTRPCContext = async () => {
// This is where you would do things like verify the user's session, etc.
const authResult = await auth();
return {
clerk: authResult,
};
};
const t = initTRPC.context<typeof createTRPCContext>().create({
transformer: superjson,
errorFormatter({ shape, error }) {
return {
...shape,
data: {
...shape.data,
zodError:
error.cause instanceof ZodError ? error.cause.flatten() : null,
},
};
},
});
export const createCallerFactory = t.createCallerFactory;
export const createTRPCRouter = t.router;
export const publicProcedure = t.procedure;
const isAuthed = t.middleware(async ({ next, ctx }) => {
if (!ctx.clerk.userId) {
throw new TRPCError({ code: "UNAUTHORIZED", message: "Not logged in" });
}
const client = await clerkClient();
const memberships = await client.users.getOrganizationMembershipList({
userId: ctx.clerk.userId,
});
const activeMembership = memberships.data.find(
(mem) => mem.organization.id === ctx.clerk.orgId,
);
return next({
ctx: {
user: ctx.clerk.userId,
CustomerId: activeMembership?.organization.publicMetadata?.customerId as string,
UserId: activeMembership?.publicMetadata?.userId as string,
},
});
});
/** Reusable middleware that enforces users are logged in before running the procedure. */
export const protectedProcedure = t.procedure.use(isAuthed);
import { initTRPC, TRPCError } from "@trpc/server";
import superjson from "superjson";
import { ZodError } from "zod";
import { auth, clerkClient } from "@clerk/nextjs/server";
// export const createTRPCContext = async (opts: { headers: Headers }) => {
export const createTRPCContext = async () => {
// This is where you would do things like verify the user's session, etc.
const authResult = await auth();
return {
clerk: authResult,
};
};
const t = initTRPC.context<typeof createTRPCContext>().create({
transformer: superjson,
errorFormatter({ shape, error }) {
return {
...shape,
data: {
...shape.data,
zodError:
error.cause instanceof ZodError ? error.cause.flatten() : null,
},
};
},
});
export const createCallerFactory = t.createCallerFactory;
export const createTRPCRouter = t.router;
export const publicProcedure = t.procedure;
const isAuthed = t.middleware(async ({ next, ctx }) => {
if (!ctx.clerk.userId) {
throw new TRPCError({ code: "UNAUTHORIZED", message: "Not logged in" });
}
const client = await clerkClient();
const memberships = await client.users.getOrganizationMembershipList({
userId: ctx.clerk.userId,
});
const activeMembership = memberships.data.find(
(mem) => mem.organization.id === ctx.clerk.orgId,
);
return next({
ctx: {
user: ctx.clerk.userId,
CustomerId: activeMembership?.organization.publicMetadata?.customerId as string,
UserId: activeMembership?.publicMetadata?.userId as string,
},
});
});
/** Reusable middleware that enforces users are logged in before running the procedure. */
export const protectedProcedure = t.procedure.use(isAuthed);
import { type inferProcedureInput } from "@trpc/server";
import { expect, test } from "vitest";
import { appRouter, type AppRouter } from "@/server/routers/_app";
import { createTRPCContext } from "@/server/init";
test("example router", async () => {
const ctx = await createTRPCContext();
const caller = appRouter.createCaller(ctx);
type Input = inferProcedureInput<AppRouter["entities"]["get"]>;
const input: Input = {
entityType: "test",
Id: "test",
};
const example = await caller.entities.get(input);
expect(example).toMatchObject({ greeting: "Hello test" });
});
import { type inferProcedureInput } from "@trpc/server";
import { expect, test } from "vitest";
import { appRouter, type AppRouter } from "@/server/routers/_app";
import { createTRPCContext } from "@/server/init";
test("example router", async () => {
const ctx = await createTRPCContext();
const caller = appRouter.createCaller(ctx);
type Input = inferProcedureInput<AppRouter["entities"]["get"]>;
const input: Input = {
entityType: "test",
Id: "test",
};
const example = await caller.entities.get(input);
expect(example).toMatchObject({ greeting: "Hello test" });
});
CustomerId
and UserId
but how do I build a test context that has this information?2 Replies
It also says
'createCaller' is deprecated.