如何在实现ngx-bootstrap/datepicker之后通过单元测试?

问题描述:

我在angular-cli项目上使用ngx-bootstrap/datepicker创建了独立组件。 一切正常,但单元测试失败。 但我是单元测试新手,我试图测试,但它说失败。如何在实现ngx-bootstrap/datepicker之后通过单元测试?

这是Travic-CI构建日志。

https://travis-ci.org/webcat12345/webcat-black-page/builds/221961698

这里是我的项目版本和代码。

@angular/cli: 1.0.0 
node: 7.6.0 
os: linux x64 
@angular/cli: 1.0.0 
@angular/common: 4.0.2 
@angular/compiler: 4.0.2 
@angular/compiler-cli: 4.0.2 
@angular/core: 4.0.2 
@angular/forms: 4.0.2 
@angular/http: 4.0.2 
@angular/platform-browser: 4.0.2 
@angular/platform-browser-dynamic: 4.0.2 
@angular/router: 4.0.2 

模板

<datepicker class="well well-sm main-calendar" [(ngModel)]="dt" [minDate]="minDate" [showWeeks]="false" [dateDisabled]="dateDisabled"></datepicker> 

组件(抱歉发布完整的代码,它是从NGX-引导演示只是示例代码)

import { Component, OnInit } from '@angular/core'; 
import * as moment from 'moment'; 

@Component({ 
    selector: 'app-sidebar-datepicker', 
    templateUrl: './sidebar-datepicker.component.html', 
    styleUrls: ['./sidebar-datepicker.component.scss'] 
}) 
export class SidebarDatepickerComponent implements OnInit { 

    public dt: Date = new Date(); 
    public minDate: Date = void 0; 
    public events: any[]; 
    public tomorrow: Date; 
    public afterTomorrow: Date; 
    public dateDisabled: {date: Date, mode: string}[]; 
    public formats: string[] = ['DD-MM-YYYY', 'YYYY/MM/DD', 'DD.MM.YYYY', 
    'shortDate']; 
    public format: string = this.formats[0]; 
    public dateOptions: any = { 
    formatYear: 'YY', 
    startingDay: 1 
    }; 
    private opened: boolean = false; 

    constructor() { 
    (this.tomorrow = new Date()).setDate(this.tomorrow.getDate() + 1); 
    (this.afterTomorrow = new Date()).setDate(this.tomorrow.getDate() + 2); 
    (this.minDate = new Date()).setDate(this.minDate.getDate() - 1000); 
    (this.dateDisabled = []); 
    this.events = [ 
     {date: this.tomorrow, status: 'full'}, 
     {date: this.afterTomorrow, status: 'partially'} 
    ]; 
    } 

    ngOnInit() { 

    } 

    public getDate(): number { 
    return this.dt && this.dt.getTime() || new Date().getTime(); 
    } 

    public today(): void { 
    this.dt = new Date(); 
    } 

    public d20090824(): void { 
    this.dt = moment('2009-08-24', 'YYYY-MM-DD') 
     .toDate(); 
    } 

    public disableTomorrow(): void { 
    this.dateDisabled = [{date: this.tomorrow, mode: 'day'}]; 
    } 

    // todo: implement custom class cases 
    public getDayClass(date: any, mode: string): string { 
    if (mode === 'day') { 
     let dayToCheck = new Date(date).setHours(0, 0, 0, 0); 

     for (let event of this.events) { 
     let currentDay = new Date(event.date).setHours(0, 0, 0, 0); 

     if (dayToCheck === currentDay) { 
      return event.status; 
     } 
     } 
    } 

    return ''; 
    } 

    public disabled(date: Date, mode: string): boolean { 
    return (mode === 'day' && (date.getDay() === 0 || date.getDay() === 6)); 
    } 

    public open(): void { 
    this.opened = !this.opened; 
    } 

    public clear(): void { 
    this.dt = void 0; 
    this.dateDisabled = undefined; 
    } 

    public toggleMin(): void { 
    this.dt = new Date(this.minDate.valueOf()); 
    } 
} 

测试代码

import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; 
import { DatepickerModule } from 'ngx-bootstrap/datepicker'; 
import { SidebarDatepickerComponent } from './sidebar-datepicker.component'; 

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

    beforeEach(async(() => { 
    TestBed.configureTestingModule({ 
     declarations: [ SidebarDatepickerComponent ], 
     schemas: [CUSTOM_ELEMENTS_SCHEMA], 
     imports: [DatepickerModule.forRoot()] 
    }) 
    .compileComponents(); 
    })); 

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

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

请帮我弄清楚这个问题。

谢谢!

1)使用NO_ERRORS_SCHEMA,而不是CUSTOM_ELEMENTS_SCHEMA因为:

CUSTOM_ELEMENTS_SCHEMA将使:

  • 在他们的名字-任何非角元素,
  • 任何性质的元素在一个-他们的名字是定制的常用规则

但你的组件没有-datepicker

NO_ERRORS_SCHEMA允许任何财产上的元素

TestBed.configureTestingModule({ 
    declarations: [ SidebarDatepickerComponent ], 
    schemas: [NO_ERRORS_SCHEMA], 
    imports: [DatepickerModule.forRoot()] 
}) 

2)另一种选择是进口FormsModule

TestBed.configureTestingModule({ 
    declarations: [ SidebarDatepickerComponent ], 
    imports: [DatepickerModule.forRoot(), FormsModule] 
}) 
+0

这是作品的魅力!我用第二个选项。还有一个问题,哪一个更适合于实践?谢谢。 – blackiii

+0

我认为这取决于你的架构。如果您知道使用NO_ERROR_SCHEMA会更好,因为您知道所有测试组件,并且已经声明并导入了所需的所有内容,请使用此选项。我更愿意控制我所有的依赖关系,并且不使用任何模式。也请查阅这篇伟大的文章https://blog.nrwl.io/essential-angular-testing-192315f8be9b – yurzui

+0

非常感谢您的帮助! – blackiii