Reputation: 1830
I am using Spectator to write my Angular 8 tests and Jest to run them. According to the README I can use setInput()
to assign my value to the name of the field, which works. The problem is that The input is being validated AFTER the component is created, but I need it before that because I use it for initialization in my ngOnInit
method:
// item.component.ts
@Input() items: Items[] = [];
ngOnInit(): void {
// do something with this.items
// read query param 'page' and use it for something
}
with
// item.component.spec.ts
let spectator: SpectatorRouting<ItemComponent>;
const createComponent = createRoutingFactory({
component: ItemComponent,
queryParams: {page: 1}
});
beforeEach(() => spectator = createComponent());
it('test items', () => {
spectator.setRouteQueryParam('page', '2');
spectator.setInput("items", myItemsList);
});
The spectator will set the queryParam page
and Input items
correctly, but only after the component is already created. During the component creation ngOnInit
will initialize with page == 1
and items == []
.
I could create the spectator component within each method and pass the queryParams separately, but I can't find a way to pass the input in the createRoutingFactory
arguments.
Alternatively I could use a host component factory to pass my input parameters, but then I lose the ability to pass query params I believe.
Upvotes: 6
Views: 8454
Reputation: 763
You can set detectChanges=false in the createRoutingFactory options. This will make createComponent() not calling onInit() automatically, and in your tests you should call spectator.detectChanges() after setting the inputs (or stubing/mocking services spys):
// item.component.spec.ts
let spectator: SpectatorRouting<ItemComponent>;
const createComponent = createRoutingFactory({
component: ItemComponent,
queryParams: {page: 1},
detectChanges: false // set this to avoid calling onInit() automatically
});
beforeEach(() => spectator = createComponent());
it('test items', () => {
spectator.setRouteQueryParam('page', '2');
// spectator.inject(AnyService).doSomething.andReturn()... // stub services if needed
spectator.setInput("items", myItemsList);
spectator.detectChanges(); // Now onInit() will be called
});
Upvotes: 17
Reputation: 1830
I found the answer to this question. It turned out to be quite simple, ngOnInit
can be called again to reinitialize the component after setting up the mocks and other parameters. So my test method becomes:
// item.component.spec.ts
let spectator: SpectatorRouting<ItemComponent>;
const createComponent = createRoutingFactory({
component: ItemComponent,
queryParams: {page: 1}
});
beforeEach(() => spectator = createComponent());
it('test items', () => {
spectator.setRouteQueryParam('page', '2');
spectator.setInput("items", myItemsList);
spectator.component.ngOnInit(); // Now the component is reinitialized and the input will contain myItemsList
});
Upvotes: -1