Unit Testing for Resolvers #961
-
Firstly, I want to express my gratitude for all the work you've put into Pothos. I have a question about unit testing for resolvers. Is there a way to accomplish this? Here is an example of what I'm trying to test: builder.queryField("users", (t) =>
t.field({
type: [User],
// 👇👇👇 I want to test this.
resolve(_parent, _args, ctx) {
return ctx.db.user.findMany();
},
})
); One method I considered was to extract the resolver function, builder.queryField("users", (t) =>
t.field({
type: [User],
resolve,
})
);
// 👇👇👇 Extract
function resolve(_parent, _args, ctx) {
return ctx.db.user.findMany();
}, but this loses type inference. I understand that it's possible to perform E2E testing by sending queries to the GraphQL server. However, I also recognize that this approach tends to be costly and can often lead to instability. By way of comparison, the library tRPC provides a createCaller method to run each procedure, which is potentially similar to a resolver. An example can be seen here: Do you have any advice on how I could approach this in Pothos? Thank you in advance. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 4 replies
-
My general approach to testing GraphQL apis is to not unit test resolvers, because things generally fall into 2 categories:
That being said, it's pretty easy to get a resolver from your schema to test. Here is an example: import {
GraphQLFieldResolver,
GraphQLObjectType,
GraphQLSchema,
defaultFieldResolver,
} from 'graphql';
const schema = builder.toSchema()
const resolver = getResolver(schema, 'Query', 'users')
export function getResolver(
schema: GraphQLSchema,
typeName: string,
fieldName: string,
): GraphQLFieldResolver<unknown, unknown> {
const type = schema.getType(typeName);
if (!(type instanceof GraphQLObjectType)) {
throw new TypeError(`Type ${typeName} is not an object type`);
}
const field = type.getFields()[fieldName];
if (!field) {
throw new Error(`Field ${field} not found on type ${type}`);
}
return field.resolve ?? defaultFieldResolver;
} This gets you the resolver along with any wrapping logic Pothos applies (eg auth checks). You can also get the unwrapped resolver from the fields extensions export function getUnwrappedResolver(
schema: GraphQLSchema,
typeName: string,
fieldName: string,
): GraphQLFieldResolver<unknown, unknown> {
const type = schema.getType(typeName);
if (!(type instanceof GraphQLObjectType)) {
throw new TypeError(`Type ${typeName} is not an object type`);
}
const field = type.getFields()[fieldName];
if (!field) {
throw new Error(`Field ${field} not found on type ${type}`);
}
return field.extensions.pothosConfig.resolve ?? defaultFieldResolver
} |
Beta Was this translation helpful? Give feedback.
My general approach to testing GraphQL apis is to not unit test resolvers, because things generally fall into 2 categories:
That being said, it's pretty easy to get a resolver from your schema to test. Here is an example: