Luis
Luis

Reputation: 2143

[Angular Unit Test]: How can I mock QueryList in a Unit Test (No integration test)

In a Content Projection scenario I have the following scenario:

// my-component.ts
 @ContentChildren(SelectOption) selectOptions: QueryList<SelectOption>;

...
ngAfterContentInit() {
    this.selectOptions.forEach((selectOption, i) => {
       selectOption.index = i;
    });
}

Assuming the template has the following structure:

<ng-content select="select-option"></ng-content>

I have tried to mock the test in the following way but I can't find an "add" method that allows me to add the child components.

// my-component.spec.ts
component.selectOptions = {} as QueryList<SelectOption>;

But I don't know how I can add the projected components in a unit test scenario (not an integration test)

Upvotes: 6

Views: 4779

Answers (2)

Peter Osifeso
Peter Osifeso

Reputation: 126

Use Object.assign() like below:

Object.assign(new QueryList(), {_results: [selectOptionMock1, selectOptionMock2, selectOptionMock3]}) as QueryList<SelectOption>;

Upvotes: 11

satanTime
satanTime

Reputation: 13574

You can use ng-mocks to mock SelectOption.

beforeEach(() => {
  return TestBed.configureTestingModule({
    declarations: [
      MyComponent,
      MockComponent(SelectOption), // or MockDirective
    ],
  }).compileComponents();
});

it('testing', () => {
  const fixture = MockRender(`
    <my-component>
      <select-option value="1"></select-option>
      <select-option value="2"></select-option>
    </my-component>
  `);

  const component = ngMocks.findInstance(MyComponent);

  expect(component.selectOptions.size).toEqual(2);
  // and other assertions.
});

Upvotes: 0

Related Questions