Angular 5 组件测试选择和触发事件

Posted

技术标签:

【中文标题】Angular 5 组件测试选择和触发事件【英文标题】:Angular 5 component testing select and triggered event 【发布时间】:2018-05-14 13:06:41 【问题描述】:

我有一个包含下拉菜单的组件。更改后,它会触发一个事件,该事件通过数组过滤以根据事件值从数组中获取 selectedProduct。

我的代码如下:

  public onProductChanged(event): void 
    this.selectedProduct = this.products.find((product: Products) => product.id == event.target.value);
  

我的选择下拉菜单:

<select id="product" (change)="onProductChanged($event)">
    <option>--- Please Select ---</option>
    <option *ngFor="let product of products" [value]="product.id">  product.displayName  </option>
</select>

产品对象是一个对象:

 "id": 1, "name": "name_here", "displayName": "Name Here" 

这一切都有效,但是我想在我的组件测试中测试更改选择值会触发事件并检索正确的值。

我的测试代码如下:

  describe('Product selection', () => 
    it('should select product', () => 

      expect(component.selectedProduct).toBeUndefined();
      productSelectElement.nativeElement.value = 'Product Name';
      productSelectElement.nativeElement.dispatchEvent(new Event('change'));

      fixture.detectChanges();

      expect(component.onProductChanged).toHaveBeenCalled();
      expect(component.selectedProduct).toEqual( "id": 1, "name": "product_name", "displayName": "Product Name" );
    );
  );

已调用 productChanged 事件并且该测试通过。但是,我的 selectedProduct 始终为空。如何使用下拉列表中的更改值触发事件?

【问题讨论】:

意思是 products 认为我试图详细说明它是一个数组,但后来忘记更改代码复制粘贴的其余部分 我认为这是一个有效的测试:component.onProductChanged('Product Name'); fixture.detectChanges();,看看它是否仍然返回 null。然后你至少知道它有效。如果它仍然返回 null 那么可能你的产品没有设置。 用 component.onProductChanged( target: value: 1 ); 试过了这不起作用。这是在应用程序中运行时传入的值,确实有​​效 那么您的产品可能没有定义。尝试使用您的第一个产品 except(component.products[0]).toBe() 进行测试。 他们是,我添加了 expect(component.products).toEqual(products);。在每个之前都是分配 components.products = products 【参考方案1】:

事实证明,在每次调用之前,我都为该函数设置了一个 spyOn,而无需通过调用。工作代码如下:

  beforeEach(() => 
    fixture = TestBed.createComponent(SelectProductsComponent);
    component = fixture.componentInstance;
    component.products = products;
    fixture.detectChanges();

    productSelectElement = fixture.debugElement.query(By.css('#products'));

    spyOn(component, 'onProductChanged').and.callThrough();

    expect(component.products).toEqual(products);
    expect(component.selectedProduct).toBeUndefined();
  );

  describe('Product selection', () => 
    it('should select product', () => 

      productSelectElement.nativeElement.value = 1;
      productSelectElement.nativeElement.dispatchEvent(new Event('change'));

      fixture.detectChanges();

      expect(component.onProductChanged).toHaveBeenCalled();
      expect(component.selectedProduct).toEqual( "id": 1, "name": "product_name", "displayName": "Product Name" );

    );
  );

【讨论】:

调度“更改”事件而不是“点击”事件对我来说是这样做的。谢谢

以上是关于Angular 5 组件测试选择和触发事件的主要内容,如果未能解决你的问题,请参考以下文章

如何使事件触发Angular2中的多个组件

Bootstrap-Vue 组件上的触发事件(测试)

Angular 5 中服务的生命周期是啥

如何从Angular 2中的子组件事件触发父组件中的本地引用?

Angular Webpack ES2015 组件构建中未触发 angular-ui-router $stateChangeStart 事件

为啥单击功能会在 Angular 2 中为自定义组件触发两次