如何在Angular中对通用组件进行单元测试

时间:2019-10-16 09:32:17

标签: angular typescript unit-testing

我正在为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';
}

这是我的规格文件,用于测试 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>

2 个答案:

答案 0 :(得分:0)

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

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

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

export class TestObject {

}

答案 1 :(得分:0)

我对这个概念的误解是:

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

BananaComponent

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

   public totalPurchase: T;
}

从上面的代码中,我们可以看到

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

  2. AppleComponent内部的情况相同,因为它是从BananaComponent扩展类型的,所以这意味着applePurchase的类型应该与bananaPurchase和totalPurchase相同。