我正在try 将单元测试添加到Angular 2应用程序中.在我的一个组件中,有一个带有(click)处理程序的按钮.当用户单击按钮时,将调用.ts类文件中定义的函数.该函数在控制台中打印一条消息.日志(log)窗口显示按钮已按下.我当前的测试代码测试console.log消息的打印:

describe('Component: ComponentToBeTested', () => {
    var component: ComponentToBeTested;

    beforeEach(() => {
        component = new ComponentToBeTested();
        spyOn(console, 'log');
    });

    it('should call onEditButtonClick() and print console.log', () => {
        component.onEditButtonClick();
        expect(console.log).toHaveBeenCalledWith('Edit button has been clicked!);
    });
});

然而,这只测试控制器类,而不是HTML.我不只是想测试当调用onEditButtonClick时是否会发生日志(log)记录;我还想测试当用户单击组件HTML文件中定义的编辑按钮时是否调用了onEditButtonClick.我该怎么做?

推荐答案

我的目标是判断用户单击编辑按钮时是否调用了"onEditButtonClick",而不仅仅是判断控制台.正在打印日志(log).

您需要首先使用Angular TestBed设置测试.这样你就可以抓住按钮并点击它.您将要做的是配置一个模块,就像配置@NgModule一样,只用于测试环境

import { TestBed, async, ComponentFixture } from '@angular/core/testing';

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

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [ ],
      declarations: [ TestComponent ],
      providers: [  ]
    }).compileComponents().then(() => {
      fixture = TestBed.createComponent(TestComponent);
      component = fixture.componentInstance;
    });
  }));
});

然后你需要监视onEditButtonClick方法,点击按钮,并判断该方法是否被调用

it('should', async(() => {
  spyOn(component, 'onEditButtonClick');

  let button = fixture.debugElement.nativeElement.querySelector('button');
  button.click();

  fixture.whenStable().then(() => {
    expect(component.onEditButtonClick).toHaveBeenCalled();
  });
}));

这里我们需要运行async测试,因为按钮click包含异步事件处理,并且需要通过调用fixture.whenStable()等待事件处理

使现代化

现在人们更倾向于使用fakeAsync/tick连击,而不是async/whenStable连击.如果进行了XHR调用,则应使用后者,因为fakeAsync不支持它.因此,与其重构上面的代码,不如

it('should', fakeAsync(() => {
  spyOn(component, 'onEditButtonClick');

  let button = fixture.debugElement.nativeElement.querySelector('button');
  button.click();
  tick();
  expect(component.onEditButtonClick).toHaveBeenCalled();

}));

别忘了输入fakeAsynctick.

另见:

Typescript相关问答推荐

打印脚本丢失函数的泛型上下文

具有泛型类方法的类方法修饰符

类型{}上不存在属性&STORE&A;-MobX&A;REACT&A;TYPE脚本

为什么在这个例子中,我把缺少的属性添加到对象中时,TypeScrip没有拾取,如何修复?

为什么有条件渲染会导致material 自动完成中出现奇怪的动画?

我可以使用TypeScrip从字符串词典/记录中填充强类型的环境对象吗?

为什么TypeScrip不能解析对象析构中的赋值?

在打字脚本中对可迭代对象进行可变压缩

tailwind css未被应用-react

如何使用TypeScrip在EXPO路由链路组件中使用动态路由?

错误TS7030:并非所有代码路径都返回值.";由tsfig.json中的";Strong";:False引起

TypeScrip:从嵌套的对象值创建新类型

如何使函数参数数组不相交?

如何创建一个将嵌套类属性的点表示法生成为字符串文字的类型?

如何处理可能为空的变量...我知道这不是Null?

如何使对象同时具有隐式和显式类型

T的typeof键的Typescript定义

React Context TypeScript错误:属性';firstName';在类型';iCards|iSearch';

带动态键的 TS 功能

Typescript 子类继承的方法允许参数中未定义的键