I have an angular library with the following structure
projects/
|..... app/
|..... src/
|..... app/
|..... app.component.spec.ts
|..... app.component.ts
|..... app.module.ts
|..... lib/
|..... sso/
|...... index.ts
|...... ng-package.json
|...... ...
|...... sso.service.ts
|...... ss.module.ts
|..... ui/
|...... menu/
|...... menu.component.ts
|...... menu.service.ts
|...... menu.module.ts
|...... index.ts
|...... ng-package.json
|..... ng-package.json
|..... package.json
|..... jest.config.ts
|..... package.json
I want to test my app.component
// app.component.ts
import {SSOService} from "my-lib/sso";
@Component({
selector: 'app-root',
template: `
<my-menu>
<router-outlet></router-outlet>
</my-menu>
`,
styleUrls: ['./app.component.scss'],
})
export class AppComponent {
constructor(protected ssoService: SSOService) { }
}
Here my current test
// app.component.spec.ts
import { TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
import {SSOService} from "my-lib/sso";
import {MenuComponent} from "my-lib/ui";
describe('AppComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [
RouterTestingModule
],
declarations: [
AppComponent, MenuComponent
],
providers: [
{
provide: SSOService,
useValue: {
setRoles: jest.fn()
}
}
]
}).compileComponents();
});
it('should create the app', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
});
});
I had to mock my sso_service even it's in the same project! But still have the same issue with MenuComponent
● Test suite failed to run
TypeError: Cannot read properties of undefined (reading 'toLowerCase')
289 | }] });
290 |
> 291 | registerLocaleData(FR);
| ^
292 | /**
293 | * Custom date adapter for Angular Material.
294 | *
at registerLocaleData (node_modules/@angular/core/fesm2022/core.mjs:22410:25)
at registerLocaleData (node_modules/@angular/common/fesm2022/common.mjs:2562:12)
at Object.<anonymous> (dist/lib/fesm2022/my-lib-ui.mjs:291:1)
at Object.<anonymous> (projects/app/src/app/app.component.spec.ts:5:1)
I don't want to mock the component too, is there an issue with library or the Jest Config maybe ?
PS: the tests works well with karma
before moving to jest
Please find below the different config files
// lib/ui/index.ts
import { CommonMenuService } from './menu/menu.service';
export * from './menu/menu.component';
export * from './menu/menu.module';
export * from './menu/menu.service';
// lib/ui/ng-package.json
{
"lib": {
"entryFile": "index.ts"
}
}
// lib/ui/pacakge.json
{
"name": "my-lib",
"version": "2.5.2",
"peerDependencies": {
"@angular/cdk": "^17.0.0",
"@angular/common": "^17.0.1",
"@angular/core": "^17.0.1",
"@angular/material": "^17.0.0",
"@awesome-cordova-plugins/in-app-browser": "^6.3.0",
"@capacitor/device": "^5.0.6",
"angular-oauth2-oidc": "^15.0.1",
"jwt-decode": "^4.0.0"
},
"dependencies": {
"tslib": "^2.6.2"
},
"sideEffects": false,
"exports": {
".": {
"sass": "./styles/_index.scss"
}
}
}
This is my Jest.config
// jest.config.ts
import type { Config } from 'jest';
const config: Config = {
clearMocks: true,
collectCoverage: true,
coverageDirectory: 'coverage',
coverageProvider: 'v8',
preset: 'jest-preset-angular',
setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'],
};
export default config;
and my tsconfig.json looks like this
// tsconfig.json
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"paths": {
"my-lib/*": ["projects/lib/*"],
"my-lib": ["projects/lib"]
},
"noFallthroughCasesInSwitch": true,
"sourceMap": true,
"declaration": false,
"downlevelIteration": true,
"experimentalDecorators": true,
"moduleResolution": "node",
"importHelpers": true,
"target": "ES2022",
"module": "ES2022",
"useDefineForClassFields": false,
"lib": ["ES2022", "dom"]
},
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"strictTemplates": true
}
}
I think that I've found an answer to my question ! it seems to have been quicker than writing the question itself ^^'
The answer was in this medium article https://fireflysemantics.medium.com/unit-testing-your-angular-library-project-with-jest-42429a8716eb
in my tsconfig.json I have
// tsconfig.json
"paths": {
"my-lib/*": ["projects/lib/*"],
"my-lib": ["projects/lib"]
},
So I have to add the following in my jest config
// jest.config.ts
moduleNameMapper: {
"^my-lib/(.*)$": "<rootDir>/projects/lib/$1",
"^my-lib/": "<rootDir>/projects/lib/",
},
yeah!it works now