【问题标题】:Testing callback functions were called with Jasmine in an Angular project在 Angular 项目中使用 Jasmine 调用测试回调函数
【发布时间】:2018-05-29 21:02:48
【问题描述】:

我的 Angular 项目中有一个面包屑组件,您可以在其中传入一个回调函数,当单击面包屑时调用该函数。

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

回调被添加到面包屑的onclick 事件中,并在用户点击一个事件时调用。

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

这是我尝试过的:

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;
}

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

谢谢。

【问题讨论】:

  • 你在 Jasmine 中尝试过 spyOn() 吗?
  • 您可以将您的面包屑数组作为值提供者注入,然后在您的单元测试中,注册一个带有回调的人工面包屑数组,该数组设置一些您可以测试的标志。您还可以将所有回调设置为 this.navService.changeView 之类的,然后注入一个假的 navService。
  • @Esaith 是的,我试过createSpy。诚然,我是 Jasmine 的新手,所以我仍在努力思考它的间谍概念。

标签: angular testing jasmine


【解决方案1】:

(我是根据我学到的东西来回答的,所以可能不对,但我觉得合乎逻辑,所以就在这里!)

当您进行单元测试时,您应该测试您编写的代码是否按预期工作。这样做是为了防止在您进行修改时产生副作用。

在您的情况下,您正在做的是测试框架是否正在完成其工作(即发出事件)。

我相信这不是您应该做的:这种测试将用于 e2e 测试,您应该从一端(前端)到另一端(后端)进行测试。

这意味着如果我是你,我只会测试面包屑的函数callback 是否符合预期。

假设它使面包屑闪烁:如果您测试面包屑是否闪烁,您将进行有用的测试。
因为如果有一天,您决定面包屑应该改变颜色而不是闪烁,那么您的测试将引发错误。
同时,如果您想测试该函数是否确实被调用,即使您彻底改变了回调的逻辑,测试也会通过。

这就是我的底线测试回调的作用,而不是它是否被调用

我希望这会有所帮助。

【讨论】:

    【解决方案2】:

    您对 create spy 的使用是正确的。在这种情况下,您也可以省略 create spy 中的名称。它在您的测试中不起作用吗?

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

    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);
          });
        });
      }));
    });
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多