I am trying to unit test a component, component and page are importing form @bloomreach/spa-sdk
export class ThinComponent implements OnInit {
@Input() component!: BrComponent;
componentModels: any;
page: Page;
constructor() {}
ngOnInit() {
this.componentModels = this.component.getModels();
}
getContents(contentRef) {
if (contentRef && contentRef.$ref) {
this.content = this.page?.getContent(contentRef).getData();
}
}
}
and my unit test like
it('should create', () => {
spyOn(component.component, 'getModels').and.returnValue({foo: 'bar'});
fixture.detectChanges();
expect(component).toBeTruthy();
});
Throwing and error TypeError: Cannot read properties of undefined (reading 'getModels')
CodePudding user response:
Ruslan Lekhman is right, you need to initialize the component
input and I don't think the spyOn
works for it. spyOn
only works for public methods.
Try this:
it('should create', () => {
component.component = { getModels: () => ({ foo: 'bar' }) };
fixture.detectChanges();
expect(component).toBeTruthy();
});
Edit:
Try changing mockPage
to something like this.
const getDataSpy = jasmine.createSpy('getData');
mockPage = { getContent: () => ({ getData: getDataSpy }) };
....
expect(getDataSpy).and.callFake(() => { return 'test'; });
Edit
Component.ts
import { Component, Input, VERSION } from '@angular/core';
import { Component as BrComponent, Page } from '@bloomreach/spa-sdk';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
name = 'Angular ' VERSION.major;
@Input() component!: BrComponent;
page: Page;
componentModels: any;
public content: any;
public image: string;
public inViewport = false;
constructor() {}
get configuration() {
return this.component.getParameters();
}
ngOnInit() {
this.componentModels = this.component?.getModels();
if (this.componentModels) {
this.getContents(this.componentModels.document);
}
}
getContents(contentRef) {
if (contentRef && contentRef.$ref) {
this.content = this.page?.getContent(contentRef).getData();
if (this.content) {
if (this.content.image) {
this.image = this.getImageUrl(this.content.image);
}
}
}
}
getImageUrl($ref): string {
return this.page.getContent($ref).getUrl();
}
onVisible(event) {
this.inViewport = true;
}
}
Component.spec.ts
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { AppComponent } from './AppComponent';
import { Component as BrComponent, Page } from '@bloomreach/spa-sdk';
describe('AppComponent', () => {
let component: AppComponent;
let fixture: ComponentFixture<AppComponent>;
beforeEach(
waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [AppComponent],
}).compileComponents();
})
);
beforeEach(() => {
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
component.component = {
getModels: () => ({ document: { $ref: {} } }),
getParameters: () => ({}),
};
component.page = {
getContent: () => ({
getData: () => ({ image: 'abc' }),
getUrl: () => 'xyz',
}),
};
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should test ngOninit', () => {
spyOn(component, 'getContents').and.callFake(() => null);
component.ngOnInit();
expect(component.getContents).toHaveBeenCalled();
});
it('should test getContents', () => {
component.getContents(component.componentModels.document);
expect(component.image).toBe('xyz');
});
});