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

7
我有一个组件,里面有一个下拉菜单。当它改变时,会触发一个事件,该事件会通过数组过滤来获取基于事件值的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”,我想我试图阐述它是一个数组,但然后忘记改变其余的代码复制粘贴。 - Steve Fitzsimons
我认为这是一个有效的测试:component.onProductChanged('产品名称'); fixture.detectChanges();,看看它是否仍然返回 null。那么你至少知道它是有效的。如果它仍然返回 null,那么可能是你的产品没有设置好。 - Swoox
尝试使用component.onProductChanged({ target: { value: 1} });,但不起作用。这是在应用程序中运行时传递的值,可以正常工作。 - Steve Fitzsimons
那么你的产品可能没有被定义。尝试使用 except(component.products[0]).toBe() 测试你的第一个产品。 - Swoox
他们是,我已经添加了 expect(component.products).toEqual(products);。在 before each 中,分配 components.products = products。 - Steve Fitzsimons
1个回答

12

结果发现在beforeEach中我设置了一个spyOn函数但没有添加callThrough。正确的代码如下:

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

    });
  });

2
发送“更改”事件而不是“单击”事件对我很有帮助。谢谢。 - jjr4826

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接