web-dev-qa-db-ja.com

Angular2は単体テストでElementRefを挿入します

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によって生成されています。今、ElementRefのインジェクションを成功させるために、beforeEachProvidersを追加する必要があるプロバイダーがあれば、それを判別できません。 _ng test_を実行すると、Error: No provider for ElementRef! (MyComponent -> ElementRef)になりました。

20
Mathieu Nls

オンAngular 2.2.3:

export class MockElementRef extends ElementRef {}

次に、テストで:

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

ElementRefを注入するには:

  1. モックを作成する
class MockElementRef implements ElementRef {
  nativeElement = {};
}
  1. テスト対象のコンポーネントにモックを提供します
beforeEachProviders(() => [Component, provide(ElementRef, { useValue: new MockElementRef() })]);

編集:これはrc4で機能していました。最終リリースでは、重大な変更が導入され、この回答が無効になりました。

7
Mathieu Nls

spyOnspyOnPropertyを使用して、必要に応じてメソッドとプロパティをインスタントモックするのが良い方法です。 spyOnPropertyには3つのプロパティが必要であり、getまたはsetを3番目のプロパティとして渡す必要があります。 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);

ここでは、get of clientWidth of div.nativeElementオブジェクト。

1
Aniruddha Das