This graphql-code-generator
plugin generates factory methods for the react-apollo MockedResponse
s that are used for testing client-side GraphQL code.
I.e. for a given query like:
query GetAuthorSummaries {
authorSummaries {
author {
name
}
}
}
This plugin will generate a newGetAuthorSummariesResponse
factory function:
export function newGetAuthorSummariesResponse(
data: GetAuthorSummariesQuery | Error,
): MockedResponse<GetAuthorSummariesQueryVariables, GetAuthorSummariesQuery> {
return {
request: { query: GetAuthorSummariesDocument },
result: { data: data instanceof Error ? undefined : data },
error: data instanceof Error ? data : undefined,
};
}
That you can use in a test like:
const response = newGetAuthorSummariesResponse({
// Use newAuthorSummary from the graphql-typescript-factories project
authorSummaries: [newAuthorSummary()],
});
// Something react-testing-library's render
const component = render(
<MockedProvider mocks={[response]}>
<YourComponent />
</MockedProvider>,
);
Or you can simulate an error with:
const response = newGetAuthorSummariesResponse(new Error("bad"));
For non-react-apollo
-specific factories for the rest of your GraphQL schema's types, see the graphql-typescript-factories sister project.
yarn add -D @homebound/graphql-typescript-response-factories
There are three well-tested patterns that this plugin supports:
- Factories in a Single File
- Factories in a Separate File
- Factories in a Separate File +
near-operation-file
imports
These patterns are automatically tested via jest in integration/
.
With this approach, you get a single file with all of your generated GraphQL code + factories. This is the easiest way to get started.
overwrite: true
schema: ./schema.json
documents: src/**/*.graphql
generates:
src/generated/graphql-types.tsx:
plugins:
- typescript
- typescript-operations
- typescript-react-apollo
- "@homebound/graphql-typescript-factories"
- "@homebound/graphql-typescript-response-factories"
See integration/singleFile/graphql-codegen.yml
for an example.
With this approach, all of your generated GraphQL code is in a single file, but your factories are in a dedicated file. This is a nice improvement to keep your test/factory logic separate from your production/runtime GraphQL code.
overwrite: true
schema: ./schema.json
documents: src/**/*.graphql
generates:
src/generated/graphql-types.tsx:
plugins:
- typescript
- typescript-operations
- typescript-react-apollo
src/generated/graphql-factories.tsx:
config:
typesFilePath: ./graphql-types
plugins:
- "@homebound/graphql-typescript-factories"
- "@homebound/graphql-typescript-response-factories"
See integration/separateFactoryFile/graphql-codegen.yml
for an example.
If you're using the near-operation-file
preset
to split your queries into separate, smaller, files, this package can figure out the imports for you. We still recommend
creating a single factory file for simplicity. Because you need to pass your near-operation-file
presetConfig
, we
recommend using a TypeScript codegen file for reusability.
// graphql-codegen.ts
import type { CodegenConfig } from "@graphql-codegen/cli";
const config: CodegenConfig = {
schema: "./schema.json",
documents: "src/**/*.graphql",
generates: {
"src/generated/graphql-types.tsx": {
plugins: ["typescript"],
},
"src/": {
preset: "near-operation-file",
presetConfig: {
...nearOperationFilePresetConfig(),
},
plugins: ["typescript-operations", "typescript-react-apollo"],
},
"src/generated/graphql-factories.tsx": {
config: {
typesFilePath: "./graphql-types",
nearOperationFilePresetConfig: {
...nearOperationFilePresetConfig(),
},
},
plugins: ["@homebound/graphql-typescript-factories", "@homebound/graphql-typescript-response-factories"],
},
},
};
function nearOperationFilePresetConfig() {
return {
extension: ".generated.tsx",
baseTypesPath: "graphql-types.tsx",
};
}
export default config;
See integration/nearOperationFile/graphql-codegen.ts
for an example.
This plugin plays nicely with @homebound/graphql-typescript-factories
,
another open-source tool to generate stubbed responses for your top-level GraphQL types.
MIT