簡體   English   中英

Angular2 在單元測試中注入 ElementRef

[英]Angular2 Inject ElementRef in unit test

我正在嘗試測試通過 DI 接收對 ElementRef 的引用的組件。

import { Component, OnInit, ElementRef } from '@angular/core';

@Component({
  selector: 'cp',
  templateUrl: '...',
  styleUrls: ['...']
})
export class MyComponent implements OnInit {

  constructor(private elementRef: ElementRef) {
    //stuffs
  }

  ngAfterViewInit() {
    // things
  }

  ngOnInit() {
  }
}

和測試:

import {
  beforeEach,
  beforeEachProviders,
  describe,
  expect,
  it,
  inject,
} from '@angular/core/testing';
import { ComponentFixture, TestComponentBuilder } from '@angular/compiler/testing';
import { Component, Renderer, ElementRef } from '@angular/core';
import { By } from '@angular/platform-browser';

describe('Component: My', () => {
  let builder: TestComponentBuilder;

  beforeEachProviders(() => [MyComponent]);
  beforeEach(inject([TestComponentBuilder], function (tcb: TestComponentBuilder) {
    builder = tcb;
  }));

  it('should inject the component', inject([MyComponent],
      (component: MyComponent) => {
    expect(component).toBeTruthy();
  }));

  it('should create the component', inject([], () => {
    return builder.createAsync(MyComponentTestController)
      .then((fixture: ComponentFixture<any>) => {
        let query = fixture.debugElement.query(By.directive(MyComponent));
        expect(query).toBeTruthy();
        expect(query.componentInstance).toBeTruthy();
      });
  }));
});

@Component({
  selector: 'test',
  template: `
    <cp></cp>
  `,
  directives: [MyComponent]
})
class MyTestController {
}

組件和測試藍圖均由 Angular-cli 生成。 現在,我不知道應該在beforeEachProviders添加哪個提供程序(如果有)才能成功注入 ElementRef。 當我運行ng test出現Error: No provider for ElementRef! (MyComponent -> ElementRef) Error: No provider for ElementRef! (MyComponent -> ElementRef)

我遇到Can't resolve all parameters for ElementRef: (?) Error using the mock from @gilad-s in angular 2.4

將模擬類修改為:

export class MockElementRef extends ElementRef {
  constructor() { super(null); }
}

解決了測試錯誤。

從這里的角度源代碼讀取: https ://github.com/angular/angular/blob/master/packages/core/testing/src/component_fixture.ts#L17-L60 夾具的 elementRef 不是從模擬創建的注射。 並且在正常開發中,我們在注入組件時不會顯式提供ElementRef 我認為TestBed應該允許相同的行為。

在 Angular 2.2.3 上:

export class MockElementRef extends ElementRef {}

然后在測試中:

beforeEach(async(() => {
  TestBed.configureTestingModule({
    providers: [
      //more providers
      { provide: ElementRef, useClass: MockElementRef }
    ]
  }).compileComponents();
}));

要注入 ElementRef:

  1. 創建一個模擬
class MockElementRef implements ElementRef {
  nativeElement = {};
}
  1. 為被測組件提供模擬
beforeEachProviders(() => [Component, provide(ElementRef, { useValue: new MockElementRef() })]);

編輯:這是在 rc4 上工作的。 最終版本引入了重大更改並使此答案無效。

一個好方法是使用spyOnspyOnProperty根據需要即時模擬方法和屬性。 spyOnProperty需要 3 個屬性,您需要將getset作為第三個屬性傳遞。 spyOn與類和方法spyOn工作並返回所需的值。

例子

const div = fixture.debugElement.query(By.css('.ellipsis-overflow'));
// now mock properties
spyOnProperty(div.nativeElement, 'clientWidth', 'get').and.returnValue(1400);
spyOnProperty(div.nativeElement, 'scrollWidth', 'get').and.returnValue(2400);

在這里我設置getclientWidthdiv.nativeElement對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM