【问题标题】:Angular how not to import all the dependencies in component unit tests each timeAngular如何不每次都导入组件单元测试中的所有依赖项
【发布时间】:2019-08-02 22:46:00
【问题描述】:

我有一个工作应用程序(运行 ng serve 时一切正常) 但是,当我运行 ng test 时,编译器抱怨无法识别指令/属性,例如 Can't bind to 'formControl' since it isn't a known property of 'input'. 当我添加时

TestBed.configureTestingModule({
      declarations: [
        AppComponent,
        SomeComponent
      ],
      imports: [
        BrowserModule,
        AppRoutingModule,
        HttpClientModule,
        .. other dependencies
    ]

不添加我已经在app.module 中添加的所有导入的聪明方法是什么?

更新:我说的是对组件进行单元测试。

【问题讨论】:

  • 你是否从 @angular/router 包中导入了 ReactiveForms 模块?尝试添加这个。
  • 没有聪明的办法。从模块到测试平台的导入可能不同(Http 是其中一种情况),需要模拟提供程序,并且根据您的测试类型,您可能不需要所有声明。如果要减少导入,则必须先减少模块。
  • 听起来你的模块做得太多了。您可能会争辩说单元测试是在告诉您重构代码。
  • @Liam 没有争论。可能的。刚开始有角度

标签: angular unit-testing angular-cli angular7


【解决方案1】:

您的测试与您的 app.module独立。所以你需要导入所有需要的模块。

如果你愿意,你可以在 shared.module.ts 那里拥有所有要测试的模块:

const MODULE_DEPENDENCIES = [
  TranslateModule,
  HttpClientModule,
  ReactiveFormsModule,
  ScrollingModule,
  MatFormFieldModule,
  MatInputModule,
];

@NgModule({
  imports: MODULE_DEPENDENCIES,
  exports: [
    ...MODULE_DEPENDENCIES
  ],
})

export class SharedModule {
  constructor() { }

  }
}

【讨论】:

  • 很好,我喜欢,谢谢。但是,会保持开放一段时间,也许有更好的方法。
  • 当然。但请记住,如果您的测试有一个共享模块,您将导入所有模块,即使是不需要的模块。如果您想确保组件的完美状态,这可能会出现问题。所以这取决于你选择了哪种策略。
【解决方案2】:

您可以创建一个包含所有指令等的 SharedModule

或者只是重用模块数组

基本上

export const modules: any[] = [
  BrowserModule, ReactiveFormsModule
];

@NgModule({
  imports:      modules,
  declarations: [ AppComponent, HelloComponent ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

在你的测试中

TestBed.configureTestingModule({
      declarations: [
        AppComponent,
        SomeComponent
      ],
      imports: modules

我不知道其他方法。

但是你可以对声明和提供者做同样的事情a并用它来节省一些输入

【讨论】:

  • 为什么投反对票? sharedmodule 或模块数组也是唯一的方法
【解决方案3】:

由于错误是无法绑定到“formControl”,因为它不是“输入”的已知属性,因此您必须在 TestBed 配置下导入以下模块。 FormsModule、ReactiveFormsModule、MatInputModule、MatFormFieldModule

例如:我在我的案例中导入了其他模块,下面是示例代码。

describe('SomeComponent', () => {
  let component: SomeComponent;
  let fixture: ComponentFixture<SomeComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [SomeComponent],
      imports: [HttpClientModule, RouterTestingModule, MatCardModule, MatIconModule, FormsModule, ReactiveFormsModule,
        MatInputModule, MatProgressSpinnerModule, MatButtonModule, MatFormFieldModule,
        BrowserAnimationsModule],
      providers: [SomeService]
    })
      .compileComponents();
  }));

  function setup() {
    const fixture = TestBed.createComponent(SomeComponent);
    const component = fixture.componentInstance;
    const someService = fixture.debugElement.injector.get(SomeService);

    return { fixture, component, someService };
    return { fixture, component };
  }

  it('should create app component', () => {
    const { component } = setup();
    expect(component).toBeTruthy();
  });


});

【讨论】:

  • 问题是完全不能再次声明“HttpClientModule、RouterTestingModule、MatCardModule、MatIconModule、FormsModule、ReactiveFormsModule、MatInputModule、MatProgressSpinnerModule、MatButtonModule、MatFormFieldModule、BrowserAnimationsModule”
猜你喜欢
  • 1970-01-01
  • 2018-01-26
  • 2020-11-21
  • 1970-01-01
  • 2019-01-09
  • 1970-01-01
  • 1970-01-01
  • 2019-06-12
  • 2019-03-21
相关资源
最近更新 更多