Невозможно проверить вход, который находится в ng-шаблоне

Как говорится в заголовке, я пытаюсь проверить вход, который находится в ng-шаблоне. Проблема в том, что я не могу получить доступ к входу. Если я беру входные данные из ng-шаблона, он работает, но мне нужно это внутри ng-шаблона.

Код для emp.html взят из документации по простым лицам. Ссылка: https://www.primefaces.org/primeng/ Раздел фильтрации

emp.html

<ng-template pTemplate="caption">         
 <div style="text-align: right">
  <i class="fa fa-search" style="margin:4px 4px 0 0"></i>
   <input type="text" pInputText size="50" placeholder="Global Filter" 
   (input)="dt.filterGlobal($event.target.value, 'contains')"
   style="width:auto">
 </div>
</ng-template>

emp.component.spec.ts

describe('EmpComponent', () => {
let component: EmpComponent;
let fixture: ComponentFixture<EmpComponent>;

beforeEach(async(() => {
  TestBed.configureTestingModule({
    imports: [SharedModule, HttpClientTestingModule],
    declarations: [ EmpComponent, TestTableComponent ],
    schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA],
    providers: [
      {provide: EmpService, useClass: MockEmpService},
    ]
  })
  .compileComponents();
}));

beforeEach(() => {
  fixture = TestBed.createComponent(EmpComponent);
  component = fixture.componentInstance;

  fixture.detectChanges();
});

it('should create', () => {
  expect(component).toBeDefined();
});

it('check input', fakeAsync(() => {

  tick();
  fixture.detectChanges();

  const inputElement = 
  fixture.debugElement.query(By.css('input')).nativeElement;// Here it fails

  inputElement.value = 'some value';
  inputElement.dispatchEvent(new Event('input'));

  fixture.whenStable().then(() => {
    fixture.detectChanges();
    expect(inputElement.value).toEqual('some value');
  });  
}))

Это приводит к следующей ошибке: Не удается прочитать свойство 'nativeElement' из null

1 ответ

Вы можете написать TestComponent, который макетирует таблицу вокруг вашего шаблона (имеется в виду тот же селектор), который просто выводит шаблоны внутри.

В своем тесте вы можете проверить все как раньше.

Обновление 1

Просто чтобы было немного яснее, что я имел в виду ранее. Вот пример того, как может выглядеть TestTableComponent. Я не писал это с редактором, так что это всего лишь пример, и он может не работать из коробки, но просто чтобы вы поняли, что я имел в виду:

@Component({
 selector: 'p-table',
 template: `<ng-content></ng-content>`
})
class TestTableComponent {
  // I haven't worked with PrimeNG before, not sure whether this type gets exported
  @ContentChildren(PrimeTemplate) templates: QueryList<PrimeTemplate>;
}

<ng-content></ng-content> должен отображать все дочерние элементы контента, которые имеют тип PrimeTemplate. Я не пробовал, хотя. Может быть необходимо получить templateRef из элементов PrimeTemplate, как это делает PrimeNG. В этом случае ваш TestTableComponent будет выглядеть примерно так:

@Component({
 selector: 'p-table',
 template: `<ng-container *ngFor="let template of templates"><ng-container *ngTemplateOutlet="template"></ng-container></ng-container>`
})
class TestTableComponent implements NgAfterContentInit{
  // I haven't worked with PrimeNG before, not sure whether this type gets exported
  @ContentChildren(PrimeTemplate) primeTemplates: QueryList<PrimeTemplate>;

  templates: TemplateRef<any>[] = [];

  ngAfterContentInit() {
    this.templates.forEach((item) => {
      this.templates.push(item.template);
    });
}

Посмотрите здесь немного больше информации о проекции контента, и это могло бы помочь взглянуть на то, как сам PrimeNG использует проекцию контента, чтобы использовать предоставленные вами шаблоны для генерации таблиц здесь.

Обновление 2

Вот стек, который демонстрирует, что я имел в виду. Я не хотел добавлять модули PrimeNG, так как я не знаю, какой из них вы используете, и не требуется знать, что я сделал. Поэтому я скопировал директиву PrimeNG (PrimeTemplate) в стек стека. Директива используется для определения всего содержимого дочерних элементов. В вашем случае все ваши ng-шаблоны в компонентах PrimeNG имеют эту директиву.

Единственный оставшийся вопрос - можно ли импортировать PrimeTemplate из PrimeNG. Вы должны попробовать это. Если PimeNG не экспортирует PrimeTemplate, вам может потребоваться написать собственную директиву и добавить ее во все ваши шаблоны, которые вы хотите протестировать. Вы можете использовать свою собственную директиву для сбора шаблонов ng. Это было бы не так хорошо, потому что вы добавили бы директиву только для целей тестирования. Поэтому я надеюсь, что PrimeNG экспортирует эту директиву.

Другие вопросы по тегам