Угловое тестирование 5: как получить ссылку на дочерний компонент

Я пытаюсь проверить взаимодействие между компонентом хоста и дочерним компонентом в приложении с угловым выражением. Я не знаю, как получить ссылку на дочерний компонент, созданный при создании родителя. Вот настройка:

child.component.spec.ts

@Component({template: '<child [data]="model"></child>'})
class HostComponent {
  public model:any;
}

describe('ChildComponent', () => {
  let hostFixture: ComponentFixture<HostComponent>;
  let childFixture: ComponentFixture<ChildComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ChildComponent, HostComponent]
    });
  }));

  beforeEach(() => {
    // this creates the child component as well, but how to get to it?
    hostFixture = TestBed.createComponent(HostComponent);

    // this creates a NEW instance of child component, not the one from the Host template
    // so it not the instance I actually want to test
    childFixture = TestBed.createComponent(ChildComponent);
  });
});

Изменение model значения в hostFixture.componentInstance на самом деле не изменить data входного значения childFixture.componentInstance; что я понял, что есть два экземпляра дочернего компонента.

Мой вопрос прост, как я могу заставить childFixture ссылаться на компонентный прибор, найденный в шаблоне HostComponent, а не на другой экземпляр, который у меня сейчас есть?

Документы не помогли.

Ответ 1

Как поясняется в руководстве, экземпляр компонента компонента создается с помощью TestBed.createComponent, а экземпляр дочернего компонента может быть выбран из debugElement с By помощника:

childDebugElement = hostFixture.debugElement.query(By.directive(ChildComponent));

Или же:

childDebugElement = hostFixture.debugElement.query(By.css('child'));

Ответ 2

Ответ выше хорош, отвечает на вопрос тела, но заголовок/заголовок вопроса спрашивает что-то еще. Кроме того, для спецификаций вам будет намного легче сосредоточиться на поведении кода компонента вместо поведения DOM. E2E лучше для простого тестирования пользовательского интерфейса (даже с ограничениями) или придерживаться простой структуры пользовательского интерфейса, которую легко проверить (например, если это значение истинно, этот элемент должен показать или нет, если это значение ложно, эта позиция должна быть меньше чем предыдущий). По этим причинам я хотел ответить на вопрос, заданный заголовком. Ответ Estus верен для конкретного варианта использования, но Google приводит вас сюда, основываясь на вопросе в названии.

Чтобы получить дочерний компонент Component, это не собственный элемент:

Тестовый компонент (называемый HostComponent в вопросе): <child [data]="model" #child></child>

Тогда в определении класса:

@Component({template: '<child #child [data]="model"></child>'})
class HostComponent {
    public model:any;
    @ViewChild('child') child;
}

Наконец, при тестировании по спецификации:

it('should do something', () => {
    component.child.value
    component.child.method
    // etc.
}