jest-preset-angular: Unable to use services exported under a namespace w/ Jest 27 + Ng12
đ Bug Report
Attempting to test components that inject a service imported from a namespace fails in Jest 27 / Angular 12.
To Reproduce
ng new my-app- Install jest / jest-preset-angular
- Create a new folder, services.
- Create a file in that folder (my-service.ts) containing the following:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class MyService {
constructor() {
console.log('HELLO')
}
}
- Create a new file (index.ts) inside the services folder containing the following:
import * as Services from './my-service';
export { Services }
- Add
private myService: Services.MyServiceto the constructor of app-component - Import Services in app-component.
- Try to run tests with
npx jest
Expected behavior
Tests run successfully
Link to repo (highly encouraged)
https://github.com/AgentEnder/ng-jest-issue-6097
Error log:
Can't resolve all parameters for AppComponent: (?).
at syntaxError (../packages/compiler/src/util.ts:108:17)
at CompileMetadataResolver.Object.<anonymous>.CompileMetadataResolver._getDependenciesMetadata (../packages/compiler/src/metadata_resolver.ts:1010:27)
at CompileMetadataResolver.Object.<anonymous>.CompileMetadataResolver._getTypeMetadata (../packages/compiler/src/metadata_resolver.ts:889:20)
at CompileMetadataResolver.Object.<anonymous>.CompileMetadataResolver.getNonNormalizedDirectiveMetadata (../packages/compiler/src/metadata_resolver.ts:387:18)
at CompileMetadataResolver.Object.<anonymous>.CompileMetadataResolver.loadDirectiveMetadata (../packages/compiler/src/metadata_resolver.ts:238:41)
at ../packages/compiler/src/jit/compiler.ts:137:36
at Array.forEach (<anonymous>)
at ../packages/compiler/src/jit/compiler.ts:135:65
at Array.forEach (<anonymous>)
at JitCompiler.Object.<anonymous>.JitCompiler._loadModules (../packages/compiler/src/jit/compiler.ts:132:71)
at JitCompiler.Object.<anonymous>.JitCompiler._compileModuleAndAllComponents (../packages/compiler/src/jit/compiler.ts:117:32)
at JitCompiler.Object.<anonymous>.JitCompiler.compileModuleAndAllComponentsAsync (../packages/compiler/src/jit/compiler.ts:69:33)
at CompilerImpl.Object.<anonymous>.CompilerImpl.compileModuleAndAllComponentsAsync (../packages/platform-browser-dynamic/src/compiler_factory.ts:69:27)
at TestingCompilerImpl.Object.<anonymous>.TestingCompilerImpl.compileModuleAndAllComponentsAsync (../packages/platform-browser-dynamic/testing/src/compiler_factory.ts:59:27)
at TestBedViewEngine.Object.<anonymous>.TestBedViewEngine.compileComponents (../packages/core/testing/src/test_bed.ts:366:27)
at Function.Object.<anonymous>.TestBedViewEngine.compileComponents (../packages/core/testing/src/test_bed.ts:155:25)
at src/app/app.component.spec.ts:10:8
at ZoneDelegate.Object.<anonymous>.ZoneDelegate.invoke (node_modules/zone.js/bundles/zone-testing-bundle.umd.js:407:30)
at ProxyZoneSpec.Object.<anonymous>.ProxyZoneSpec.onInvoke (node_modules/zone.js/bundles/zone-testing-bundle.umd.js:3765:43)
at ZoneDelegate.Object.<anonymous>.ZoneDelegate.invoke (node_modules/zone.js/bundles/zone-testing-bundle.umd.js:406:56)
at Zone.Object.<anonymous>.Zone.run (node_modules/zone.js/bundles/zone-testing-bundle.umd.js:167:47)
at Object.wrappedFunc (node_modules/zone.js/bundles/zone-testing-bundle.umd.js:4250:34)
envinfo
System:
OS: Ubuntu (tested under wsl2)
Npm packages:
jest: 27.0.5
jest-preset-angular: 9.0.4
typescript: 4.2.3
About this issue
- Original URL
- State: open
- Created 3 years ago
- Reactions: 8
- Comments: 39
@Maximaximum I just found a new workaround that you can adjust your
tsconfig.spec.jsonto haveat least it fixed the issue with the sample repo.
The problem I think is similar to #1199 is that: Angular doesnât support transpile
tstojsin âisolated wayâ. Angular always requires one single TypeScriptProgram(see https://github.com/angular/angular/issues/43165) to process all the files together while here with Jest, we split them up into multiple workers. Compilation per worker is not the same as using one singleProgram.I am using generated code from
apollo-angularlike @Maximaximum and was able to fix the issue with anngccrun and the replacement ofwith
in
tsconfig.spec.jsonCurrently using jest-preset-angular@9.0.7
This doesnât seam to work with nx repos and graphql codegen đ
@ahnpnl Any news regarding properly fixing this issue within
jest-preset-angular?@ahnpnl Iâm currently trying to implement a custom Jest resolver, but it seems like a customer resolver wonât be able to fix the issue.
Letâs take a
import * as Apollo from 'apollo-angular';line as an example.As far as I can see, a Jest resolver only deals with resolving
importpaths likeapollo-angularto actual absolute file paths in the filesystem (like/workspaces/my-project/frontend/node_modules/apollo-angular/bundles/ngApollo.umd.js). But it has nothing to do with handling the* as Apollopart. The resolver doesnât even get the* as Apollo(or anything like{ gql }orsomeDefaultExport) part as an argument, it has no idea about what values are actually being imported from an es6 module.Iâm facing exactly the same issue! (And it took me a few days to trace it down!).
The issue only happens with Jest (not with Jasmine/Karma) and only if using namespace imports, ie
import * as Exported from './exported';.In my case the issue is that Iâm using some code generated by a 3rd party code generator that contains namespace imports, and thereâs no way to tweak the code generatorâs behavior
I guess all the logic to desugar namespace syntax lies here https://github.com/Maximaximum/jest-namespace-imports-transformer/blob/main/src/transform-script.ts#L88 ? We are happy to add it as a custom AST transformer to internal codes
@ahnpnl I donât know about the exact use cases of the other folks here, but in my specific case I have dozens of auto-generated files containing namespaced imports. Adding an entry to
jest.config.jsfor each of these imports is definitely not an option, because Iâm having annxworkspace with about 20 different angular projects, and each of them having its ownjest.config.js. Managing all thesemoduleNameMappersettings in all of thejest.config.jswould be a nightmare!Creating a custom resolver might be an option, but Iâm totally new to Jest, so it might be quite an overwhelming task for me.
As per using
path-mappingtransformer, it looks like it should be relatively easy to do though. Will give it a try, thank you.IIRC
ng builddoes similar thing likengc.ngcis a replacement oftscwhich does some Angular things extra.After producing build outputs, you would need to configure Jest to run on output folder yes.