Angular 4 Component @Input ngOnInit未调用

时间:2018-01-13 00:55:10

标签: angular

我的Component数据成员受@Input约束ngOnInit()似乎无法调用。该组件的代码如下:

import { Component, OnInit, Input } from '@angular/core';
import { SelectedStatusConstants } from '../../constants/selected-status.constants';
import { AutoUnsubscribe } from '../../decorator/auto-unsubscribe.decorator';
import { ChartScale } from '../../models/chart-scale.model';
import { SkillsetService } from '../../services/skill-set-service/skill-set.service';
import { NgZone } from '@angular/core';

@Component({
  selector: 'app-skillset',
  templateUrl: './skillset.component.html',
  styleUrls: ['./skillset.component.css']
})

/**
 * The skillset component
 * @author : Michael Warren
 */
@AutoUnsubscribe
export class SkillsetComponent implements OnInit {
  /**
   * The selected status 
   */
  @Input() selectedStatus : string = SelectedStatusConstants.TRAINING;
  /**
   * Map of selected status to skill id
   */
  private static SKILL_INFO : Map<String, any>;
  /**
   * The id of skill, probably to hit the API with
   */
  private skillID : number;
  /**
   * The flag that tells Angular, and the developer, whether or not ng2_chart dependency is actually being used
   */
  USE_NG2_CHART : boolean = true;
  /**
   * The types of charts
   */
  public static readonly chartTypes = {
    BAR : 'bar',
    PIE : 'pie',
    POLAR_AREA : 'polarArea'
  }
  /**
   * The type of chart
   */
  chartType = SkillsetComponent.chartTypes.BAR;
  /**
   * The dummy data to compare against for our tests
   */
  readonly DUMMY_DATA = [{data:[1,1,1,1,1], label: 'Mapped'},{data:[1,1,1,1,1],label: 'Unmapped'}];
  /**
   * The skillset data
   */
  skillsetData = this.DUMMY_DATA;
  /**
   * THe skillset labels
   */
  skillsetLabels = [];
  /**
   * The chart options, as a JavaScript-style object, and pre-initialized so as to DRY up our code...
   */
  chartOptions : {[k: string]: any} = {
    type : this.chartType,
    legend : {
      display : false
    },
    xAxes:[
      {
        ticks: {
          autoSkip:false
        }
      }
    ],
    scales : new ChartScale()
  };

  constructor(private skillsetService : SkillsetService, private zone : NgZone) {
    // setup SKILL_INFO
    if (!SkillsetComponent.SKILL_INFO) {
      SkillsetComponent.SKILL_INFO = new Map();
      SkillsetComponent.SKILL_INFO.set(SelectedStatusConstants.TRAINING, 6);
      SkillsetComponent.SKILL_INFO.set(SelectedStatusConstants.OPEN, 7);
      SkillsetComponent.SKILL_INFO.set(SelectedStatusConstants.SELECTED, 8);
      SkillsetComponent.SKILL_INFO.set(SelectedStatusConstants.CONFIRMED, 9);
    }
  }

  ngOnInit(): void {
    // get skillID
    this.skillID = SkillsetComponent.SKILL_INFO.get(this.selectedStatus) || 0;
    // get the skillset data here
    this.skillsetService.getSkillsetsForStatusID(this.skillID).subscribe((res) => {
      // copy in the raw data into local variable
      let skillsets : Array<any> = res.data;
      // map() that variable into skillsetData,skillsetLabels
      this.skillsetData  = skillsets.map((obj) => obj.count);
      this.skillsetLabels= skillsets.map((obj) => obj.name);
    });
  }

  /**
   * Exposing SKILL_INFO in a safe way
   */
  public static getSkillInfo() {
    return SkillsetComponent.SKILL_INFO;
  }

}

此组件不以任何方式路由,因为用例是使用其标记名称,属性绑定selectedStatus。当我在此组件上编写测试时,为了确保其skillsetDataDUMMY_DATA不同,它会失败。 (我确保测试了服务方法,然后通过了。)SkillsetComponent的测试如下:

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

import { SkillsetComponent } from './skillset.component';
import { SelectedStatusConstants } from '../../constants/selected-status.constants';
import { element, by, browser } from 'protractor';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { ChartsModule } from 'ng2-charts';
import { RootComponent } from '../root/root.component';
import { HomeComponent } from '../home/home.component';
import { NavbarComponent } from '../navbar/navbar.component';
import { RouterTestingModule } from '@angular/router/testing';
import { SkillsetService } from '../../services/skill-set-service/skill-set.service';

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

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ SkillsetComponent, RootComponent, HomeComponent, NavbarComponent ],
      imports : [
        HttpClientTestingModule, 
        ChartsModule,
        RouterTestingModule
      ],
      providers : [
        SkillsetService
      ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(SkillsetComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  it('should have a non-empty map of skill info', () => {
    expect(SkillsetComponent.getSkillInfo()).toBeTruthy();
    expect(SkillsetComponent.getSkillInfo().size).toBeGreaterThan(0);
  });

  it('should have non-zero skillID', () => {
    component.selectedStatus = SelectedStatusConstants.CONFIRMED;
    expect(component.selectedStatus).toBeTruthy();
  })

  it('should not be using DUMMY_DATA', () => {
    expect(component.skillsetData).not.toEqual(component.DUMMY_DATA);
  })
});

如何确保调用此ngOnInit(),或者测试是否正确加载数据?

1 个答案:

答案 0 :(得分:3)

从这个项目的压力现实中放松一下,然后再回到它,我意识到这个测试:

依赖于ngOnInit()更改数据,并通过了。因此,问题不是ngOnInit(),而是我的测试本身。我找到了this resource

it('should have non-zero skillID', () => {
    component.selectedStatus = SelectedStatusConstants.CONFIRMED;
    expect(component.selectedStatus).toBeTruthy();
  })

并重构了我的测试,但没有:

it('should not be using DUMMY_DATA', () => {
    fixture.detectChanges();
    fixture.whenStable().then(() => {
      expect(component.skillsetData).not.toEqual(component.DUMMY_DATA);
    })
  });

console.log('Stress makes people do stupid desperate things, especially when said stress comes from super tight deadlines')