36

I have a pipe that sanatises HTML as below:

import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';

@Pipe({
    name: 'sanitiseHtml'
})

export class SanitiseHtmlPipe implements PipeTransform {

constructor(private _sanitizer: DomSanitizer) {}

    transform(value: any): any {
      return this._sanitizer.bypassSecurityTrustHtml(value);
    }

}

I want to test it as below:

describe('Pipe: Sanatiser', () => {
    let pipe: SanitiseHtmlPipe;

    beforeEach(() => {
        pipe = new SanitiseHtmlPipe(new DomSanitizer());
    });

    it('create an instance', () => {
        expect(pipe).toBeTruthy();
    }); 
});

The DomSanatizer is an abstract class which is autowired by typescript by passing it into a constructor:

constructor(private _sanitizer: DomSanitizer) {}

Currently I get the typescript errror:

Cannot create an instance of the abstract class 'DomSanitizer'.

Does anyone know what typescript does when instantiating dependencies passed into a constructor in Angular? Or what the way to test something like this is?

4

3 回答 3

65

由于你的管道中有 DI,你需要配置一个测试环境(测试台)来解决依赖关系:

import { BrowserModule, DomSanitizer } from '@angular/platform-browser';
import { inject, TestBed } from '@angular/core/testing';

describe('SanitiseHtmlPipe', () => {
  beforeEach(() => {
    TestBed
      .configureTestingModule({
        imports: [
          BrowserModule
        ]
      });
  });

  it('create an instance', inject([DomSanitizer], (domSanitizer: DomSanitizer) => {
    let pipe = new SanitiseHtmlPipe(domSanitizer);
    expect(pipe).toBeTruthy();
  })); 
});
于 2017-11-27T17:26:39.620 回答
16

万一有人想重用 Pipe 的构造函数,您可以使用 TestBed 来获得相同的结果:

  let pipe: SafeHtmlPipe;
  let sanitized: DomSanitizer

  beforeEach(async() => {
    TestBed.configureTestingModule({
      providers: [DomSanitizer]
    });
    sanitized = TestBed.get(DomSanitizer);
    pipe = new SafeHtmlPipe(sanitized);
  });

  it('create an instance', () => {
    expect(pipe).toBeTruthy();
  });
于 2019-11-05T10:45:38.637 回答
3

如果您想模拟整个提供程序并且不想使用构造函数,我就是这样做的(使用 Jest,但用您的常规 jasmine.createSpyObj 替换间谍)

规格

describe("MyPipe", () => {
  let pipe: MyPipe;
  const myServiceSpy = { myFunction: jest.fn() };

  beforeEach(() => {
    jest.clearAllMocks();
    TestBed.configureTestingModule({
      providers: [
        MyPipe,
        {
          provide: MyService,
          useValue: myServiceSpy
        }
      ]
    });

    pipe = TestBed.inject(myPipe);
  });

  it("create an instance", () => {
    expect(pipe).toBeTruthy();
  });
});

管道

@Pipe({
  name: "myPipe"
})
export class MyPipe implements PipeTransform {
  constructor(private readonly myService: MyService) {}

  transform(value: Item): boolean {
    // stuff with your service
    return true;
  }
}
于 2020-11-05T09:35:12.357 回答