skip to Main Content

I am writing an Angular application, and it just happens that one of the third-party components happens to be in React. I wrote a wrapper NG component to render the React one, and it works beautifully giving the desired result. However, this setup messes up all the test cases giving the dreaded error:

Cannot read properties of undefined (reading ‘ɵcmp’)

The test cases are written in jest.

React Component

export const ReactoComponent: FunctionComponent<IProps> = (props: IProps) => {
  return (
    <div className={`reacto-component`}>
      <span>Counter: {props.counter}</span>
    </div>
  );
};

Angular Wrapper

@Component({
  selector: 'wrapper',
  standalone: true,
  templateUrl: './wrapper.component.html',
})
export class WrapperComponent implements AfterViewInit {
  counter = 42;

  @ViewChild('myReactContainer', { static: false }) container!: ElementRef;

  ngAfterViewInit() {
    this.render();
  }

  render() {
    const { counter } = this;
    ReactDOM.render(
      <div className={'wrapper'}>
        <ReactoComponent counter={counter} />
      </div>,
      this.container.nativeElement
    );
  }
}

Wrapper Test

describe('WrapperComponent', () => {
  let component: WrapperComponent;
  let fixture: ComponentFixture<WrapperComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [WrapperComponent],
    }).compileComponents();

    fixture = TestBed.createComponent(WrapperComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

Error

Expected value   undefined
Received:
  undefined

Message:
  Cannot read properties of undefined (reading 'ɵcmp')

jest.config

module.exports = {
  preset: 'jest-preset-angular',
  setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'],
  globalSetup: 'jest-preset-angular/global-setup',
  testMatch: ['**/*.test.ts'],
};

How do I fix the unit tests?

I was able to replicate the error using a simple Stackblitz: https://stackblitz.com/edit/stackblitz-starters-se1ssj
(run npm run test on the Stackblitz console)

2

Answers


  1. You probably need to configure jest to properly take .tsx files otherwise it can’t find them so that you’re getting undefined

    jest.config.js

    module.exports = {
      preset: 'jest-preset-angular',
      setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'],
      globalSetup: 'jest-preset-angular/global-setup',
      testMatch: ['**/*.test.ts'],
      moduleFileExtensions: ['ts', 'tsx', 'js', 'json'],  // add these
      transform: {                                        // two options
        '^.+\.(tsx)?$': 'ts-jest',
      },
    };
    
    Login or Signup to reply.
  2. The error should be likely due to the fact that Angular’s standalone components are not yet fully supported in your testing setup. To fix this, you can try the below steps:

    • Ensure Angular and Jest are properly configured: Make sure you have the necessary dependencies and configurations for Jest and Angular.

    • Update the TestBed configuration: Since WrapperComponent is a standalone component, you need to ensure that it is properly imported and declared in the TestBed configuration.

    You can update the test file as follow:

    import { ComponentFixture, TestBed } from '@angular/core/testing';
    import { WrapperComponent } from './wrapper.component';
    import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
    
    describe('WrapperComponent', () => {
      let component: WrapperComponent;
      let fixture: ComponentFixture<WrapperComponent>;
    
      beforeEach(async () => {
        await TestBed.configureTestingModule({
          imports: [WrapperComponent],
          schemas: [CUSTOM_ELEMENTS_SCHEMA], // Add this line
        }).compileComponents();
    
        fixture = TestBed.createComponent(WrapperComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
      });
    
      it('should create', () => {
        expect(component).toBeTruthy();
      });
    });

    Explanation:
    We have added CUSTOM_ELEMENTS_SCHEMA that allows the use of custom elements (like your standalone component) in the template without throwing errors.

    • Note: Please ensure proper imports. Make sure that WrapperComponent is imported in the TestBed.configureTestingModule properly.

    Safety Checks:

    • Check your Jest Configuration: Ensure that your Jest configuration (jest.config.js) is properly setup and you’re able to test the application if this test class is excluded.
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search