在Angular项目中使用Jasmine调用了测试回调函数

Kol*_*lby 8 testing jasmine angular

我在Angular项目中有一个breadcrumbs组件,你传入一个回调函数,当单击面包屑时会调用它.

用户传入一个对象,该对象包含用于呈现面包屑的信息,以及单击面包屑时的回调.

回调被添加到breadcrumb的onclick事件中,并在用户单击一个时调用.

<li *ngFor="let breadcrumb of breadcrumbs">
  <span (click)="breadcrumb.callback()">{{breadcrumb.title}}</span>
</li>
Run Code Online (Sandbox Code Playgroud)

这就是我尝试过的:

beforeEach(async(() => {
  TestBed.configureTestingModule({
    declarations: [BreadcrumbsTestComponent, Breadcrumbs]
  });
}));

it('should call given callback when breadcrumb is clicked', async(() => {
  const fixture = TestBed.createComponent(BreadcrumbComponent);
  fixture.detectChanges();

  const breadcrumbElements = fixture.nativeElement.querySelectorAll('.breadcrumb');

  breadcrumbElements.forEach(breadcrumb => {
    breadcrumb.click();
    fixture.whenStable().then(() => {
      expect(breadcrumb.callback).toHaveBeenCalled();
    });
  });
}));

const breadcrumbs = [
  {
    title: 'First Page',
    path: '/first',
    current: false,
    callback: jasmine.createSpy('callback')
  }, {
    title: 'Second Page',
    path: '/second',
    current: true,
    callback: jasmine.createSpy('callback')
  }
];

@Component({
  template: `<breadcrumbs [breadcrumbs]="breadcrumbs"></breadcrumbs>`
})
class BreadcrumbsTestComponent {
  breadcrumbs = breadcrumbs;
}
Run Code Online (Sandbox Code Playgroud)

如何测试我的Jasmine测试中是否调用了回调?

谢谢.

Ale*_*esD 0

您对创建间谍的使用是正确的。在这种情况下,您还可以在创建间谍时省略名称。在你的测试中它不起作用吗?

您可以更改的是不创建测试组件,而直接测试面包屑组件。在这种情况下,我认为您不需要包装器组件,它只会使事情变得复杂。那么测试将如下所示:

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

import { BreadcrumbsComponent } from './breadcrumbs.component';
import { Breadcrumb } from '../breadcrumb/breadcrumb';
import { By } from '@angular/platform-browser';

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

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ BreadcrumbsComponent ]
    })
    .compileComponents();
  }));

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

  it('should call given callback when breadcrumb is clicked', async(() => {
    const breadcrumbs: Breadcrumb[] = [
      {
        title: 'First Page',
        path: '/first',
        current: false,
        callback: jasmine.createSpy()
      }, {
        title: 'Second Page',
        path: '/second',
        current: true,
        callback: jasmine.createSpy()
      }
    ];
    component.breadcrumbs = breadcrumbs;
    fixture.detectChanges();
    const breadcrumbElements = fixture.debugElement.queryAll(By.css('span'));

    breadcrumbElements.forEach(breadcrumb => {
      breadcrumb.nativeElement.click();
    });

    fixture.whenStable().then(() => {
      breadcrumbs.forEach(breadcrumb => {
        expect(breadcrumb.callback).toHaveBeenCalledTimes(1);
      });
    });
  }));
});
Run Code Online (Sandbox Code Playgroud)

我使用第一个框中的代码作为面包屑组件的代码,这就是为什么我随后查询 span 元素以在测试中单击它们的原因。