Closed hendrikgaffo closed 2 years ago
I think we have similar issue after upgrading from angular 11 to 12. For each such generated service
@Injectable({
providedIn: 'root'
})
export class MyGQL extends Apollo.Mutation<MyMutation, MyMutationVariables> {
document = MyDocument;
constructor(apollo: Apollo.Apollo) {
super(apollo);
}
}
I get this error while testing with jest:
This constructor is not compatible with Angular Dependency Injection because its dependency at index 0 of the parameter list is invalid.
This can happen if the dependency type is a primitive like a string or if an ancestor of this class is missing an Angular decorator.
Please check that 1) the type for the parameter at index 0 is correct and 2) the correct Angular decorators are defined for this class and its ancestors.
Shouldn't the ApolloBase
be @Injectable
?
Test works fine if I comment out the service.
I have the same as @pafflique with generated code, it started after upgrading to jest 27.
regarding the error message and angular doc's, ApolloBase
should have the @Injectable
decorator anyway.
But I could also workaround by changing the generated code to not use namespace import:
import * as Apollo from 'apollo-angular';
to
import { Apollo as ApolloClient, Query as ApolloQuery, Mutation as ApolloMutation) from 'apollo-angular';
and changing the respective references too.
I started with this test, because I found some jest-preset-angular
issues related to namespace imports.
I'm still now sure how and if this is related to the missing @Injectable
decorator and if both can fix the problem.
just did a test. putting
Injectable()(ApolloBase);
in test-setup.ts (jest setup file) of the app to test, it works without changing the generated code. So it seems, that the decorator would also fix the problem.
Injectable()(ApolloBase);
didn't help for me.
Here are some related issues:
@WolfSoko
Injectable()(ApolloBase);
didn't help for me.
I found too my workaround was instable. But maybe I found it which could also fix your problem.
In my case I had to import ApolloBase
and Apollo
at in the test-setup.ts
to be sure it worked.
Found this out, as I wanted to use the same workaround in a lib, which did not import Apollo
.
So my current workaround is:
/**
* TODO: workaround for https://github.com/kamilkisiela/apollo-angular/issues/1703
*
* has to be called in `test-setup.ts`:
*
* ```
* import { Apollo, ApolloBase } from 'apollo-angular';
* import { fixApolloBase } from './workaround';
* fixApolloBase(Apollo, ApolloBase);
*
* ```
*
* @param _apollo `Apollo` has to be imported by the caller (forces the called to do so)
* @param apolloBase `ApolloBase` has to be imported by the caller (forces the called to do so)
* @returns
*/
export function fixApolloBase(
_apollo: typeof Apollo,
apolloBase: typeof ApolloBase
) {
return Injectable()(apolloBase);
}
Then import and execute the function from within test-setup.ts
. The arguments forces the caller (test-setup.ts
) in this case to import the required classes:
import { Apollo, ApolloBase } from 'apollo-angular';
import { fixApolloBase } from './workaround';
fixApolloBase(Apollo, ApolloBase);
At least in my case this helped in multiple libs.
@spali How does your jest.config look like. Above workaround does not work for me right now.
@Nielsb85 I use an NX workspace with default generated jest.config.
the workspace jest.config.js
:
const { getJestProjects } = require('@nrwl/jest');
module.exports = { projects: getJestProjects() };
the workspace jest.preset.js
:
const nxPreset = require('@nrwl/jest/preset');
module.exports = { ...nxPreset };
the library jest.config
:
module.exports = {
displayName: 'graphql-client',
preset: '../../jest.preset.js',
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
globals: {
'ts-jest': {
tsconfig: '<rootDir>/tsconfig.spec.json',
stringifyContentPathRegex: '\\.(html|svg)$',
},
},
coverageDirectory: '../../coverage/libs/graphql-client',
transform: {
'^.+\\.(ts|js|html)$': 'jest-preset-angular',
},
snapshotSerializers: [
'jest-preset-angular/build/serializers/no-ng-attributes',
'jest-preset-angular/build/serializers/ng-snapshot',
'jest-preset-angular/build/serializers/html-comment',
],
};
@Nielsb85 I forget to mention.... be sure to clear jest cache before running tests and if it's a NX workspace to skip the nx-cache --skip-nx-cache
. This made me some headages ... due inconsistent results.
Just be sure to always clear the cache before every test run and always skip the nx-cache during testing this workaround.
@spali Thanks. Cache was already cleared. No luck so far.
I used a "direct flavor" of the workaround.
import { Injectable } from '@angular/core';
import { ApolloBase } from 'apollo-angular';
Injectable()(ApolloBase);
It has been very difficult to trace this issue to its actual cause, but this is the actual bug: https://github.com/thymikee/jest-preset-angular/issues/963
The issue appears because jest-preset-angular
does not support namespace imports like import * as Apollo from 'apollo-angular'
, and graphql-codegen
puts such lines into its generated files.
thanks Maximaximum
Describe the bug
We are using NX for our monorepo and created a library that is responsible for the generation and exposure of GraphQL services using codegen as suggested here. Using said services in our components works just fine. However, when it comes to testing (Jest), we get an error saying:
Can't resolve all parameters for GetExampleGQL: (?).
To Reproduce
1. Create a Library with nx using the following
codegen.yml
and export the generated services2. Use the generated services in a Jest test
3. Run tests
Outputs:
Expected behavior
The test should pass.
Environment:
It would be nice if someone could share if I am doing something wrong in the test.