Karma测试Angular X(5)组件,其中包含使用内置管道的自定义管道

时间:2018-06-14 09:14:21

标签: angular unit-testing typescript karma-jasmine

我已经构建了一个自定义管道来格式化货币,它使用了十进制管道。现在我想要Karma测试我的组件,它使用我的自定义管道。

这是我的自定义管道:

import { Pipe, PipeTransform } from "@angular/core";
import { CURRENCY } from "./customCurrency.enums";
import { DecimalPipe } from "@angular/common";

type CurrencySymbol = keyof typeof CURRENCY;
type CurrencyHandler = {
  [x in CurrencySymbol]: (value: string) => string;
};

@Pipe({
  name: "customCurrency",
})
export class CustomCurrencyPipe implements PipeTransform {

  constructor(private decimalPipe: DecimalPipe) { }

  transform(amount: string, currency: CurrencySymbol): string {
    const currencyHandler: CurrencyHandler = {
      Euro: (value: string): string => {
        const formatValue = value.toString().replace(",", ".");
        return this.setCharAt(formatValue, formatValue.length - 3, ",") + " " + CURRENCY.Euro;
      },
    };

    return currencyHandler[currency](this.decimalPipe.transform(amount, "1.2-2"));
  }

  private setCharAt(str, index, chr) {
    if (index > str.length - 1) {
      return str;
    }
    return str.substr(0, index) + chr + str.substr(index + 1);
  }
}

我只在我的组件的HTML部分中使用它: <span class="col-s currency">{{invoice.totalAmount | customCurrency:"Euro"}}</span>

此管道是我的SharedModule的成员。所以我将它导入我的testbed配置。

现在我想在这里用这个模板测试组件:

/* tslint:disable:no-unused-variable */
import { async, ComponentFixture, TestBed } from "@angular/core/testing";
import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";

import { ApprovalsComponent } from "./approvals.component";
import { MaterialModule } from "../shared/material.module";
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { DataService } from "../core/data.service";
import { SharedModule } from "../shared/shared.module";

describe("ApprovalsComponent", () => {
  let component: ApprovalsComponent;
  let fixture: ComponentFixture<ApprovalsComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        MaterialModule,
        BrowserAnimationsModule,
        SharedModule,
      ],
      declarations: [
        ApprovalsComponent,
      ],
      providers: [
        DataService,
      ],
      schemas: [CUSTOM_ELEMENTS_SCHEMA],
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(ApprovalsComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

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

我总是收到错误: NullInjectorError: No provider for DecimalPipe!

我尝试过各种导入或声明变体,但没有成功。我究竟做错了什么? 有人可以说,我必须导入/声明/提供什么。我的自定义管道是共享模块的一部分。如果我想测试使用它的组件但是在不同的模块中该怎么办?如果我想在同一模块中的组件中使用管道怎么办?

1 个答案:

答案 0 :(得分:0)

我重新启动了我的完整环境并再次将DecimalPipe添加到我的提供商,现在它可以运行了。我不知道为什么它现在可以工作而且之前没有,但是当我在另一个模块时,它适用于这种配置:

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        MaterialModule,
        BrowserAnimationsModule,
        SharedModule,
      ],
      declarations: [
        ApprovalsComponent,
      ],
      providers: [
        DataService,
        DecimalPipe,
      ],
      schemas: [
        CUSTOM_ELEMENTS_SCHEMA,
      ],
    })
    .compileComponents();
  }));

当我在同一模块时使用此配置:

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        MaterialModule,
      ],
      declarations: [
        LineItemListComponent,
        CustomCurrencyPipe,
      ],
      schemas: [
        CUSTOM_ELEMENTS_SCHEMA,
      ],
      providers: [
        DecimalPipe,
      ],
    })
    .compileComponents();
  }));