角度7:断言将正确的数据传递给结构指令的更好方法是什么?

时间:2019-03-11 07:29:53

标签: angular unit-testing testing mocking angular-directive

我正在为使用Angular 材料组件 Angular 应用编写单元测试。而且我一直坚持以正确的方式测试使用材料表的组件,因为它具有如下所示的结构指令

<mat-table [dataSource]="classifications$ | async">
  <mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></mat-header-row>
</mat-table>

我已经搜索了Internet和StackOverflow,以找到一种更好的方法来处理它,就像可以使用ComponentInstance的常规指令和组件一样,但是我没有找到使用的方法>结构指令。因此,为了解除封锁,我想出了一个骇人的解决方案,它有一个context对象,该对象将成为结构指令中设置的容器。

我还需要在结构指令中调用this.viewContainer.createEmbeddedView(this.templateRef);以获取呈现的组件,因为我还想断言它存在于模板中。 / p>

如果您知道更好的方法,请给我指路;) 预先谢谢你!

下面您可以看到我当前的测试:

import { Component, Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';

const context: any = {};

@Directive({ selector: '[appShow]' })
export class ShowDirective {
  constructor(
    private templateRef: TemplateRef<any>,
    private viewContainer: ViewContainerRef,
  ) {}

  @Input() set appShow(show: boolean) {
    context.show = show;

    this.viewContainer.createEmbeddedView(this.templateRef);
  }
}

@Component({
  template: `
    <h1>STRUCTURAL DIRECTIVE TEST displayExtraHeader: {{displayExtraHeader}}</h1>
    <h2 *appShow="displayExtraHeader">Lorem ipsum</h2>
  `,
})
class StructuralDirectiveComponent {
  displayExtraHeader = true;
}

describe('Structural Directive', () => {
  let component: StructuralDirectiveComponent;
  let fixture: ComponentFixture<StructuralDirectiveComponent>;
  let compiled: any;

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

  beforeEach(() => {
    fixture = TestBed.createComponent(StructuralDirectiveComponent);
    compiled = fixture.debugElement.nativeElement;
    component = fixture.componentInstance;
  });

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

  describe('HTML', () => {
    beforeEach(() => {
      delete context.show;
      component.displayExtraHeader = false;
      fixture.detectChanges();
    });

    it('should render <h1>', () => {
      expect(compiled.querySelector('h1')).not.toBeNull();
    });
    it('should pass displayExtraHeader to appShow', () => {
      const directive1: any = fixture.debugElement.query(By.css('[appShow]'));
      const directive2: any = fixture.debugElement.query(By.directive(ShowDirective));

      console.log(`>>> directive1`, directive1);
      console.log(`>>> directive2`, directive2);

      // directive1 and directive 2 are null
      // @TODO: how to get an instance of structural directive?

      expect(context.show).toEqual(false);
    });
  });
});

0 个答案:

没有答案