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)
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',
},
};