Angular selectRootElement与应用程序一起使用而不与测试一起使用

时间:2019-05-22 20:53:49

标签: angular attributes angular-renderer2

我的Angular应用程序要求以以下方式将数据传递到页面上的根组件:

    <application-root testVar="hello world"></application-root>

经过大量研究,我决定不使用ElementRef来访问属性,而是改用Renderer2。我的AppComponent构造函数设置如下:

    @Component({
      selector: 'application-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.scss']
    })
    export class AppComponent implements OnInit {
      public data: string;
      constructor(private renderer: Renderer2)
      {
        this.data = this.renderer.selectRootElement('application-root', true).getAttribute('testVar');
      }
      ..
    }

当我在应用程序中运行此程序时,没有任何错误,并且获得了“ hello world”值。但是,当我尝试运行单元测试用例时,出现以下错误:“选择器“ application-root”与任何元素都不匹配“。这是我的测试用例:

    describe('AppComponent', () => {
      beforeEach(async(() => {
      TestBed.configureTestingModule({
        imports: [
          RouterTestingModule,
          HttpClientTestingModule
        ],
        declarations: [
          AppComponent
        ],
        providers: [
          {provide: Router, useValue: routerSpy},
          Renderer2
        ]
      }).compileComponents();
      fixture = TestBed.createComponent(AppComponent);
      component = fixture.componentInstance;
      }));
      it('should create the app', () => {
        expect(fixture).toBeTruthy();
      });

现在,如果将我的selectRootElement调用从构造函数中移出,并移到ngOnInit()函数中,则我的单元测试用例通过了,但是当我尝试运行该应用程序时,我得到了一个空白屏幕。

我需要在代码中做什么才能允许我访问可以在应用程序中正确运行的根组件属性并通过单元测试用例?

1 个答案:

答案 0 :(得分:0)

所以我想出的解决方案是将所有内容移出构造函数,并移入ngOnInit()函数。当我对运行该应用程序进行重新测试时,它实际上可以正常工作,并且屏幕上没有任何内容。但是,为了使此功能适用于单元测试用例,我了解到必须将元素本身添加到beforeEach函数中。

当Angular使用AppComponent执行其单元测试用例时,呈现的模板是一个标签,而不是众所周知的选择器。因此,为了使应用程序能够获取该元素,我们将首先创建该元素,然后将属性设置为该元素,以便在运行测试脚本时,它将在模板中识别该元素:

    let appElement: ElementRef;
    let renderer2: Renderer2;
    describe('AppComponent', () => {
      beforeEach(async(() => {
      TestBed.configureTestingModule({
        imports: [
          RouterTestingModule,
          HttpClientTestingModule
        ],
        declarations: [
          AppComponent
        ],
        providers: [
          {provide: Router, useValue: routerSpy},
          Renderer2
        ]
      }).compileComponents();
      fixture = TestBed.createComponent(AppComponent);
      renderer2 = fixture.componentRef.injector.get<Renderer2>(Renderer2 as Type<Renderer2>);
      appElement = renderer2.createElement('application-root');
      renderer2.appendChild(fixture.nativeElement, appElement);
      component = fixture.componentInstance;
      }));
      it('should create the app', () => {
        expect(fixture).toBeTruthy();
      });

如果有更好的方法来解决这个问题,我全神贯注。