【问题标题】:How to unit test a generic component in Angular如何在 Angular 中对通用组件进行单元测试
【发布时间】:2020-02-13 01:09:23
【问题描述】:

我正在为 AppleComponent 编写一个测试,其类型为 <T,U extends BananaComponent<T>>。还有BananaComponent<T>

目标组件

export class AppleComponent<T,U extends BananaComponent<T>>{
   public appleA = 'appleA';
   public appleB = 'appleB';
   public appleC !: U;

}

扩展组件

export abstract class BananaComponent<T> implements OnInit{
   public bananaA = 'bananaA';
   public bananaB = 'bananaB';
}

这是我的 spec 文件,用于测试 AppleComponent

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

import {AppleComponent} from '....';
import {BananaComponent} from '....';

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

   beforeEach(()=>{
     TestBed.configureTestingModule({
         declarations:[AppleComponent],
         imports:[BananaComponent],
     });
     fixture = TestBed.creatComponent(AppleComponent);
     component = fixture.componentInstance;
   });

   it('should with defaults',() => {
      expect(component.appleA).toBe('appleA','appleA has appleA as default value'); // passes
   });
});

因此我的规范文件有问题,无法编译。

我的逻辑是组件和夹具的类型错误,我想我需要对组件和夹具进行一些更改,然后得出我在下面写的答案。

// first inside the test to define a random type, then give it to AppleComponent, and BananaComponent.

type typeA = { };  
type typeModel = AppleComponent<typeA, BananaComponent<typeA>>;   

let component: typeModel; 
let fixture: ComponentFixture<typeModel>

【问题讨论】:

  • 测试中的AppleComponent实际上并没有扩展Banana组件,那么它如何使用香蕉组件的属性。
  • 是的,谢谢,这是有道理的,我只是误解了整个上下文。但是如果我需要进行测试,我需要以正确的方式编写组件,夹具。例如类型类型 A = { };类型 typeModel = AppleComponent>;让组件:typeModel;让夹具:ComponentFixture
  • 您的查询已解决?
  • 是的,解决了

标签: angular typescript unit-testing


【解决方案1】:

您是否尝试在创建过程中提供组件的类型?

fixture = TestBed.createComponent<AppleComponent<TestObject>>(AppleComponent)

您可能应该创建一个不适用于通用类型 T 的 TestObject 模型。

export class TestObject {

}

【讨论】:

  • 能否请您也写下如何创建TestObject 模型。谢谢
  • 坦克很多。这是有效的:fixture = TestBed.createComponent>(AppleComponent)
【解决方案2】:

我对这个概念的误解是:

AppleComponent 并不是真正从 BananaComponent 扩展而来,因此 component. 将永远无法从 BananaComponent 获得任何东西。

这里发生的只是 AppleComponent 的类型扩展了 BananaComponent;目的是保持 AppleComponent 内部输入值的类型与 BananaComponent 内部输入值的类型相同。

因此在测试过程中仍然需要以正确的方式编写组件、夹具。

我提出的问题的解决方案

// first inside the test to define a random type, then give it to AppleComponent, and BananaComponent.

type typeA = { };  
type typeModel = AppleComponent<typeA, BananaComponent<typeA>>;   

let component: typeModel; 
let fixture: ComponentFixture<typeModel>

为了更好的理解 AppleComponent 和 BananaComponent 的类型之间的关系,这里有更详细的代码。

AppleComponent

export class AppleComponent<T,U extends BananaComponent<T>>{
   public appleA = 'appleA';
   public appleB = 'appleB';
   public applePurchase !: U;
}

香蕉组件

export abstract class BananaComponent<T> implements OnInit{
   public bananaA = 'bananaA';
   public bananaB = 'bananaB';
   public bananaPurchase : T;

   public totalPurchase: T;
}

从上面的代码我们可以看出

  1. 在 BananaComponent 内部,类型 T 是为了确保输入的bananaPurchase 与 totalPurchase 具有相同的类型,例如当香蕉购买 = 1000;那么类型设置为数字,那么totalPurchase的值也必须是数字,反之亦然。

  2. AppleComponent 内部的情况相同,因为它扩展了 BananaComponent 的类型,因此这意味着 applePurchase 应该与bananaPurchase 和 totalPurchase 具有相同的类型。

【讨论】:

  • 你现在有什么问题?
猜你喜欢
  • 1970-01-01
  • 2017-01-09
  • 1970-01-01
  • 1970-01-01
  • 2019-11-02
  • 2021-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多