Angular 5:在单元测试时如何处理组件依赖关系?

时间:2018-04-12 19:58:23

标签: angular unit-testing

我是Angular 5应用程序环境中的单元测试新手。 而现在,我正在尝试对基本组件进行单元测试。

该组件名为CardComponent,在此组件的HTML中,我调用CheckboxComponent 所以这是CardComponent的HTML:

<div>
    <p>Test</p>
    <jg-checkbox [label]="'Test label'"></jg-checkbox>
</div>

正如你所看到的,没有什么比这复杂的了。

但是,CheckboxComponent确实会注入服务。为了这个问题,我将其称为TestService。

所以当我对我的CardComponent进行单元测试时,这是我的测试平台:

TestBed.configureTestingModule({
    declarations: [
        CheckboxComponent
    ]
}).compileComponents();

然后我运行这个测试:

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

这只是通过CLI创建的默认测试。

但现在,它抱怨TestService没有提供者。我真的应该注射(和模拟/间谍)吗?

这看起来有些倒退,因为我只关心CardComponent,我不应该关心CheckboxComponent,对吧?这是单元测试的重点。

否则,由于Angular具有分层组件,因此随着应用程序的增长,我可能不得不深入到很多级别。

这不可能是正确的。

有人可以帮忙解决这个问题吗?我很感激帮助!

3 个答案:

答案 0 :(得分:3)

如果没有必要引用CheckboxComponent中的CardComponent,则有两种方法:

  • CheckboxComponent可以存根
  • NO_ERRORS_SCHEMA可以在TestBed.configureTestingModule({})
  • 中使用

该文档有一个关于Nested component tests

的部分

还有一个关于Shallow component tests

的答案

<强>成株

card.component.spec.ts

中创建存根组件
@Component({selector: 'jg-checkbox', template: ''})
class CheckboxStubComponent {}

然后在TestBed.configureTestingModule({})中声明这一点。

TestBed.configureTestingModule({
  declarations: [
    CardComponent,
    CheckboxStubComponent
  ]
})

<强> NO_ERRORS_SCHEMA

可以使用

NO_ERRORS_SCHEMA代替存根。

TestBed.configureTestingModule({
  declarations: [
    CardComponent
  ],
  schemas: [ NO_ERRORS_SCHEMA ]
})
  

NO_ERRORS_SCHEMA告诉Angular编译器忽略无法识别的元素和属性。

任何一种方法都是可以接受的。但是,文档中有关于过度使用NO_ERRORS_SCHEMA的警告。

  

NO_ERRORS_SCHEMA还会阻止编译器告诉您无意中或拼写错误的遗漏组件和属性。你可能会浪费数小时追逐编译器会在瞬间捕获到的幻像错误。

它还提到存根还有其他优势。

  

存根组件方法还有另一个优点。虽然此示例中的存根是空的,但如果您的测试需要以某种方式与它们进行交互,则可以为它们提供精简模板和类。

它继续展示如何根据测试需要一起使用这两种方法。

答案 1 :(得分:0)

是的,您需要创建一个模拟服务,该服务涵盖您的组件在ngOnInit()函数中调用的每个服务函数。

export class MockTestService {
    public myFunction() {

   }
}

...
describe('TheComponent', () => {
   const svc = new MockTestService();

...
TestBed.configureTestingModule({
declarations: [],
providers: [{provide: TestService, useValue: svc}]
}

})compileComponents();

答案 2 :(得分:0)

虽然如果你只是使用TestBed ,@ josavish的回答是正确的,NO-ERRORS-SCHEMA会掩盖模板中的错误,并且手动创建的存根组件可能会失去同步快速导致测试失败时再次通过(再次掩盖真正的错误)!

这正是我写shallow-render的原因。使用Shallow,模拟复选框组件将是自动的。

使用以下方式设置测试:

const shallow: Shallow<CardComponent>;
beforeEach(() => {
  shallow = new Shallow(CardComponent, TheModuleCardComponentIsDeclaredIn);
});

请注意,通过提供模块,您将能够自动使用模块中可用的组件(以及它的依赖项)。基本上,您将获得具有相同输入/输出属性的jg-checkbox模拟。

然后,您可以使用以下规范验证组件的渲染:

it('renders a checkbox with the correct label', async () => {
  const {findComponent} = await shallow.render();
  const checkbox = findComponent(CheckboxComponent);

  expect(checkbox.label).toBe('Test Label');
});

有很多示例规范here和完整的readme

希望这有帮助!