Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jest fails to load Primeng css files

I'm using Jest version 26.6.3 to test Angular components. The unit tests for any components that use Primeng's checkbox component fail during the compileComponents step with the error "Failed to load checkbox.css":

Failed: "Failed to load checkbox.css"

       7 |
       8 | describe('CheckboxComponent', () => {
    >  9 |   beforeEach(async () => {
         |   ^
      10 |     await TestBed.configureTestingModule({
      11 |       imports: [CheckboxModule],
      12 |       declarations: [CheckboxComponent, FieldLabelComponent],

      at Env.beforeEach (node_modules/jest-jasmine2/build/jasmineAsyncInstall.js:46:24)
      at context.<computed> (node_modules/zone.js/bundles/zone-testing-bundle.umd.js:4309:39)
      at Suite.<anonymous> (src/app/@shared/forms/checkbox/checkbox.component.spec.ts:9:3)
      at ZoneDelegate.Object.<anonymous>.ZoneDelegate.invoke (node_modules/zone.js/bundles/zone-testing-bundle.umd.js:407:30)
      at Zone.Object.<anonymous>.Zone.run (node_modules/zone.js/bundles/zone-testing-bundle.umd.js:167:47)
      at Suite.<anonymous> (node_modules/zone.js/bundles/zone-testing-bundle.umd.js:4227:33)

There are no files in my codebase named checkbox.css and no references to it anywhere either, so I'm assuming the css file is from Primeng. I've tried including schemas: [NO_ERRORS_SCHEMA] in the TestBed.configureTestingModule options, with no changes.

What might be causing this error? I'll include some relevant files below:

This is the full test function that fails

import { TestBed } from '@angular/core/testing';
import { FormControl } from '@angular/forms';
import { CheckboxModule } from 'primeng/checkbox';
import { createComponent, getControlDisplayValue } from 'src/tests/test-utils';
import { FieldLabelComponent } from '../form-field/field-label/field-label.component';
import { CheckboxComponent } from './checkbox.component';

describe('CheckboxComponent', () => {
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [CheckboxModule],
      declarations: [CheckboxComponent, FieldLabelComponent],
    }).compileComponents();
  });

This is the template for the component:

<p-checkbox [inputId]="inputId" [formControl]="control" [binary]="true" [class.small-checkbox]="small"></p-checkbox>
<label [for]="inputId" [class.small-label]="small">
  <app-field-label [label]="label" [required]="required" [extraSmall]="small"></app-field-label>
</label>

Here's the jest.config.js file:

module.exports = {
  preset: "jest-preset-angular",
  roots: ["src"],
  coverageDirectory: "reports",
  setupFilesAfterEnv: ["<rootDir>/src/setup-jest.ts"],
  moduleNameMapper: {
    "@app/(.*)": "<rootDir>/src/app/$1",
    "@core": ["<rootDir>/src/app/@core"],
    "@core/(.*)": ["<rootDir>/src/app/@core/$1"],
    "@shared": ["<rootDir>/src/app/@shared"],
    "@shared/(.*)": ["<rootDir>/src/app/@shared/$1"],
    "@env": "<rootDir>/src/environments/environment",
  },
  globals: {
    "ts-jest": {
      allowSyntheticDefaultImports: true,
      tsconfig: "<rootDir>/tsconfig.spec.json",
    },
  },
  // Do not ignore librairies such as ionic, ionic-native or bootstrap to transform them during unit testing.
  transformIgnorePatterns: ["node_modules/(?!(jest-test|@ng-bootstrap))"],
};

And here's the tsconfig.spec.json file

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/spec",
    "allowJs": true,
    "types": ["jest", "node"]
  },
  "files": ["src/setup-jest.ts", "src/polyfills.ts"],
  "include": ["src/**/*.spec.ts", "src/**/*.mock.ts", "src/**/*.d.ts"]
}
like image 779
Nathan Taylor Avatar asked Sep 21 '21 17:09

Nathan Taylor


1 Answers

It looks like this issue is caused by Primeng components failing to load css files specified in the styleUrls of the component decorator when tests run. I was able to resolve this by adding the following code inside the beforeEach function and before calling TestBed.configureTestingModule:

TestBed.overrideComponent(Checkbox, { set: { styleUrls: [] } });

Because multiple Primeng components were causing this error in some of my tests, I eventually pulled the TestBed.overrideComponent call into a helper function:

export function removeStyleUrlsFrom(tokens: Type<any>[]): void {
  tokens.forEach((token) => TestBed.overrideComponent(token, { set: { styleUrls: [] } }));
}

This can be used in this way:

beforeEach(async () => {
  removeStyleUrlsFrom([Checkbox, Calendar, Dropdown]);
  await TestBed.configureTestingModule({
    imports: [
      CheckboxModule,
      CalendarModule,
      DropdownModule,
    ],
    .....
  }).compileComponents();
like image 183
Nathan Taylor Avatar answered Oct 12 '22 06:10

Nathan Taylor