Angular中的浅层测试-覆盖模板-这是一种好习惯吗?

时间:2018-07-10 07:20:04

标签: angular unit-testing

我有一个关于在Angular单元测试中覆盖模板的假想问题(如果这不是一个合适的问题,请建议关闭而不是将其标记下来,我将删除/关闭该问题)。我的团队成员更喜欢在Angular中进行单元测试时覆盖HTML模板,因此,如果我进行了测试,它将看起来像这样:

describe('MyWhateverComponent', () => {
  let component: MyWhateverComponent;
  let fixture: ComponentFixture<MyWhateverComponent>;
  // lots more things here removed

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        MyWhateverComponent
      ],
      schemas: [...],
      imports: [...],
      providers: [...]
    }).overrideTemplate(MyWhateverComponent, '<div>Overridden template</div>')
      .compileComponents();
  }));

我的同事似乎喜欢这样做的原因,因为他们说这使他们只能测试组件代码(包含在.ts文件中),这使我们不必模拟或包含指令,而我们不想测试诸如ngIfngForngClass等之类的Angular绑定...好参数,但对我来说似乎是错误的,因为我认为您应该测试视图中呈现的内容防止意外行为或内容。这个论点似乎并不能使我的同事感到安心,其他任何人都可以提出建议或思考为什么在Angular中对组件进行单元测试时不应该覆盖模板的其他原因。在我看来,我们的测试本质并未真正解决我们的真正问题。我会假设(因为我没有做任何检查)浅层测试会更快地执行另一个支持同事的理由。

任何想法或意见都应事先得到赞赏。

2 个答案:

答案 0 :(得分:2)

如果他们只想测试组件的逻辑,那么他们就不应使用Angular上下文(也称为“测试平台”),而只需像下面这样创建组件的新实例:

describe('MyWhateverComponent', () => {
  const component = new MyWhateverComponent(/* injection */);
  it('...', () => {...});
});

testing guide中所述:

  

但是,组件不仅仅是其类。组件与DOM和其他组件进行交互。仅限班级的测试可以告诉您有关班级行为的信息。他们无法告诉您该组件是否要正确渲染,响应用户输入和手势或与其父子组件集成。

     

以上所有仅用于类的测试都不能回答有关组件在屏幕上实际行为的关键问题。
  -Lightswitch.clicked()是否绑定到任何可以使用户调用的内容?
  -是否显示Lightswitch.message
  -用户可以实际选择DashboardHeroComponent显示的英雄吗?
  -英雄名称是否按预期显示(即大写)?
  -WelcomeComponent的模板是否显示欢迎消息?

另外,作为一个注释,对服务/组件/指令的模拟仅进行一次,因此要做的并不是那么大。

答案 1 :(得分:2)

我认为,不应该覆盖被测试组件的完整模板。模拟子组件很好,但不模拟实际组件。

几个原因:

  1. 您可能在组件中使用@ViewChild(),引用了模板中的某些dom元素或子组件。因此,您一定会松开它。
  2. 我相信,组件测试更多是关于测试视图模板(渲染),而不是implementationbehaviour(方法)。
  3. 组件用于面对用户,因此需要用户输入。因此,您的测试应更多地集中在从视图中获取输入并测试输出。 (不是直接调用该方法并期望它已被调用)

    ex:

    spyOn(comp, 'calculate');
    comp.calculate();
    expect(comp.calculate).toHaveBeenCalled();