未创建受测角度指令

时间:2019-05-15 20:04:10

标签: angular unit-testing

我正在尝试对Angular指令进行单元测试。我已经对另一个指令进行了一些单元测试,这些指令运行正常。这是typeahead-input.directive.ts文件的内容:

@Directive({
  selector: '[hsaTypeaheadInput]',
})
export class TypeaheadInputDirective implements AfterContentInit {
  private destroy$: Subject<boolean> = new Subject<boolean>();

  @Input() typeaheadDebounceTime: number = 300;
  @Output() valueChanged: EventEmitter<string> = new EventEmitter<string>();

  constructor(private searchInput: ElementRef) {}

  ngAfterContentInit() {
    this.setupTypeaheadObservable();
  }

  ngOnDestroy() {
    this.destroy$.next(true);
  }

  setupTypeaheadObservable() {
    fromEvent(this.searchInput.nativeElement, 'keyup')
      .pipe(
        map((ev: KeyboardEvent) => {
          if (ev && ev.key === 'Escape') {
            this.searchInput.nativeElement.blur();
          }
          return ev;
        }),
        filter(
          (ev: KeyboardEvent) =>
            ev.key !== TypeaheadKeys.ENTER &&
            ev.key !== TypeaheadKeys.UP &&
            ev.key !== TypeaheadKeys.DOWN &&
            ev.key !== TypeaheadKeys.ESC,
        ),
        debounceTime(this.typeaheadDebounceTime),
        distinctUntilChanged(),
        tap(() => this.valueChanged.emit(this.searchInput.nativeElement.value)),
        takeUntil(this.destroy$),
      )
      .subscribe();
  }
}

本质上,创建一个可观察对象以在debounceTime之后输出新值。当我在Stackblitz中对其进行测试时,该可观察的作品就可以了。但是现在我正在尝试为此编写测试,这就是我遇到问题的地方。至于测试设置,我创建了一个TestHostComponent

@Component({
  selector: 'app-test-host',
  template: `
    <input hsaTypeaheadInput type="text" />
  `,
})
class TestHostComponent implements AfterViewInit {
  @ViewChild(TypeaheadInputDirective) typeaheadInputDirective: TypeaheadInputDirective;
  public typeaheadDebounceTime: number = 300;
  valueChanged(newValue: string) {}

  ngAfterViewInit() {
    console.log(this.typeaheadInputDirective);
  }
}

此测试组件上的AfterViewInit代码只是为了查看typeaheadInputDirective是否可用。不是,它是未定义的。

这是其余的测试设置:

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

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [TestHostComponent, TypeaheadResultDirective],
    }).compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(TestHostComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

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

第一个测试实际上有效; component变量是真实的。但是该指令永远不会实例化或运行。我不确定为什么。我在这里做错了什么,导致指令无法创建?

1 个答案:

答案 0 :(得分:2)

在配置测试模块时,您具有以下声明:

declarations: [TestHostComponent, TypeaheadResultDirective]

但是,您的组件正在使用TypeaheadInputDirective,该类型未在测试模块中声明。

您应该更新声明以包含指令:

declarations: [TestHostComponent, TypeaheadResultDirective, TypeaheadInputDirective]