Angular 4 : Jasmine: Failed: Uncaught (in promise): TypeError: Cannot read property 'nativeElement' of null

标签 angular unit-testing karma-jasmine

我正在 Angular 4 应用程序中使用 jasmine 编写单元测试用例。我每次都收到“无法读取 null 的属性‘nativeElement’”,我不知道为什么。下面我要做的是检查按钮是否被点击。以下是我的代码文件。


规范文件

import { Http, Response, RequestOptions, Request, ConnectionBackend } from '@angular/http';
import { DataShareService } from '../core/services/data-share.service';
import { scooterRepairService } from './services/scooterRepair.service';
import { Router } from '@angular/router';

import { scooterRepairUnitComponent } from './scooter-repair-Unit.component';
import { TestBed, ComponentFixture, async, inject } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement, NO_ERRORS_SCHEMA } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { SelectItem, CheckboxModule, CalendarModule, MultiSelectModule } from 'primeng/primeng';
import { CoreUIModule } from 'core-ui';
import { RouterTestingModule } from '@angular/router/testing';


describe('scooterRepairUnitComponent', () => {
    let fixture: ComponentFixture<scooterRepairUnitComponent>;
    let component: any;
    let http: Http;
    let dataShare: DataShareService;
    let scooterRepairService: scooterRepairService;
    let router: Router
    let comp = new scooterRepairUnitComponent(http, dataShare, scooterRepairService, router);

    // service stubs to mock services
    let MockResponse = {
        navigate: jasmine.createSpy('Response')
    }

    let MockRequestOptions = {
        navigate: jasmine.createSpy('RequestOptions')
    }

    let MockRequest = {
        navigate: jasmine.createSpy('Request')
    }

    let MockConnectionBackend = {
        navigate: jasmine.createSpy('ConnectionBackend')
    }

    // async beforeEach
    beforeEach(async(() => {

        TestBed.configureTestingModule({
            declarations: [scooterRepairUnitComponent], // declare the test component
            imports: [FormsModule, CheckboxModule, CalendarModule, MultiSelectModule, CoreUIModule, RouterTestingModule],
            schemas: [NO_ERRORS_SCHEMA],
            providers: [Http,
                { provide: Response, useValue: MockResponse },
                { provide: RequestOptions, useValue: MockRequestOptions },
                { provide: Request, useValue: MockRequest },
                { provide: ConnectionBackend, useValue: MockConnectionBackend },
                DataShareService,
                scooterRepairService]

        })
            .compileComponents();  // compile template and css
        fixture = TestBed.createComponent(scooterRepairUnitComponent);
        component = fixture.componentInstance;
    }));



    // synchronous beforeEach -- used if component is having external templates
    beforeEach(() => {

        comp = new scooterRepairUnitComponent(http, dataShare, scooterRepairService, router);
    });   



    it('should', async(() => {
        spyOn(component, 'onClearClick');
         let de: DebugElement = fixture.debugElement.query(By.css('#clearSearch'));
         let el: HTMLElement = de.nativeElement;
        fixture.whenStable().then(() => {


            fixture.detectChanges();
            expect(component.onClearClick).toHaveBeenCalled();
        })
    }));

组件.ts

import { Component, OnInit, ViewEncapsulation, ElementRef, Output, Input } from '@angular/core';
import { Pipe, PipeTransform, Inject } from '@angular/core';
import { Http, Response, RequestOptions, Request, ConnectionBackend } from '@angular/http';
import { IScooter } from './models/Scooter';
import { IShop } from './models/shop';
import { ISelectedTab } from './models/selectedTab';
import { RestClientService, EnvironmentService } from 'core-shared/core.service';
import { Observable } from 'rxjs/Observable';
import { DataShareService } from '../core/services/data-share.service';
//mport { CommonService } from '../shared/services/common.service';
import { NgForm, FormBuilder, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { SelectItem } from 'primeng/primeng';
import { ScooterRepairService } from './services/ScooterRepair.service';


@Component({
    selector: 'Scooter-repair-Unit',
    templateUrl: './Scooter-repair-Unit.component.html',
    styleUrls: ['./Scooter-repair-Unit.component.scss'],
    encapsulation: ViewEncapsulation.None,
})

export class ScooterRepairUnitComponent {
    selectedTab: string = 'ScooterRepair';
    showRepairUnitSelection: boolean=true;
    showScooterRepairUnit:boolean=true;

    showShopRepairUnit:boolean=false ;
    showMissingRepairUnit:boolean=false;
    showAddScooterRepairUnit:boolean=false;
    showAddShopRepairUnit: boolean = false;
    showScooterRepairUnitResultGrid = false;

    ScooterRepairUnitSearchTitle= 'Search Scooter Repair Unit Threshold';
    ScooterRepairUnitSearchResult= 'Scooter Repair Unit Results';
    shopRepairUnitSearchTitle= 'Search Shop Repair Unit Threshold';
    shopRepairUnitSearchResult= 'Shop Repair Unit Results';
    missingRepairUnitSearchResult= 'Missing Repair Unit Results';
    updateRepairUnitTitle= 'Update Results';
    gridPageSize: number;

    Scooters: IScooter[];

    errorMessage: string;

    ScooterRepairs: IScooter[] = [];
    canSubmitAuditRequest = false;
    totalScooterRepairRecords: number;
    isValidated: boolean;
    isSubmittedSuccessfully: boolean;
    clearScooterRepairSearch: boolean;

    constructor(private http: Http,
        private dataShare: DataShareService,
      //  private commonService: CommonService,
        private ScooterRepairService: ScooterRepairService,
       // private loggerService: LoggerService,
       // private storageService: StorageService,
        private router: Router) {
        this.gridPageSize = 10;
    }
     onSelectionChange(tabname) {
        this.SetTab(tabname);
     }


  private SetTab(tabname: string){
    this.showScooterRepairUnit = false;
         this.showShopRepairUnit = false ;
         this.showMissingRepairUnit = false;
     if (tabname === 'ScooterRepair') {
         this.showScooterRepairUnit = true;
     }

     if (tabname === 'shopRepair') {
         this.showShopRepairUnit = true ;
    }
    if (tabname === 'missingRepair') {
         this.showMissingRepairUnit = true;
      }
}

   ngOnInit(): void {
        this.setBreadCrumb();
        this.setLastSearch();
        this.selectedTab = 'ScooterRepair';
    }

   private setBreadCrumb() {
        // Setting Page title
        this.dataShare.setData('appTitle', 'Repair Unit Maintenance');

        // Setting Breadcrumb
        this.dataShare.setData('breadcrumbItems', [
        { label: 'Business Rule Engine' },
        { label: 'Repair Unit Maintenance', url: '/cra' }
    ]);
    }


    onClearClick()
    {
        this.clearScooterRepairSearch = true;
    }

}

HTML 文件

<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12" *ngIf="showRepairUnitSelection">
    <div class="panel ">
<form class="form-horizontal scooterUnitSearchForm" #requestauditsearchform="ngForm" action="#" >

                <div class="form-group ">  
                    <div class="col-lg-12 col-xs-12 clearfix">
                    <label for="" class=" col-lg-2 col-xs-6 control-label">
                        Search By:
                    </label>              
                    <label class="control-label radio-inline">
                                <input  type="radio" id="showscooter" name="mainTab" [(ngModel)]="selectedTab" value="scooterRepair" (change)="onSelectionChange(selectedTab)" 
                                 [checked]="selectedTab === scooterRepair">
                                    scooter Repair Unit 
                    </label>
                     <label class=" control-label radio-inline">
                              <input type="radio"  name="mainTab"  id="showShop"  [(ngModel)]="selectedTab" value="shopRepair" (change)="onSelectionChange(selectedTab)" 
                                [checked]="selectedTab === shopRepair"> 
                             Shop  Repair Unit 
                     </label>
                    <label class=" control-label radio-inline">
                              <input type="radio"  name="mainTab"    id="showMissingscooter"  [(ngModel)]="selectedTab" value="missingRepair"(change)="onSelectionChange(selectedTab)" 
                               [checked]="selectedTab === missingRepair"> 
                             Missing scooter Repair Unit
                     </label>

                </div>
                </div>           
</form>
</div>
  </div>

<div class="col-lg-12 col-mg-12 col-sm-12 col-xs-12">
    <collapse-expand-frame 
        [frametitle]="scooterRepairUnitSearchTitle" *ngIf="showscooterRepairUnit">
        <scooter-repair-Unit-search

            (requestscooterRepairSearch)="searchscooterRepairRequest($event)" 
            [clearscooterRepairSearch]="clearscooterRepairSearch"
        >
        </scooter-repair-Unit-search>
    </collapse-expand-frame> 

</div>


<div class="row" style="Margin-bottom:20px" *ngIf="showscooterRepairUnit">
                <div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 ">
                <div class="form-group">
                    <div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 text-sm-right text-md-right text-right">
                    <button pButton type="button" label="Add Repair Unit" (click)="onAddscooterRepair()" class="btn btn-default"></button>
                    <button pButton type="button" label="Search" class="btn btn-default"></button>
                    <button pButton type="button" label="Clear" (click)="onClearClick()" class="btn btn-default"></button>                
                    </div>
                </div>
            </div>
              </div>
<div class="col-lg-12 col-mg-12 col-sm-12 col-xs-12 clearfix"  *ngIf="showAddscooterRepairUnit">


<collapse-expand-frame >
        <add-scooter-repair-Unit

            (requestscooterRepairSearch)="searchscooterRepairRequest($event)" 
        >
        </add-scooter-repair-Unit>
</collapse-expand-frame >

</div>

<div class="col-lg-12 col-mg-12 col-sm-12 col-xs-12">
<collapse-expand-frame 
    [frametitle]="scooterRepairUnitSearchResult" *ngIf="showscooterRepairUnit">
    <scooter-repair-Unit-search-grid 

    >
    </scooter-repair-Unit-search-grid >
</collapse-expand-frame>
</div>

<div class="col-lg-12 col-mg-12 col-sm-12 col-xs-12">
<collapse-expand-frame 
    [frametitle]="updateRepairUnitTitle" *ngIf="showscooterRepairUnit">
    <update-scooter-repair-Unit
    >
    </update-scooter-repair-Unit>
</collapse-expand-frame>
</div>

<div class="col-lg-12 col-mg-12 col-sm-12 col-xs-12">
    <collapse-expand-frame 
        [frametitle]="shopRepairUnitSearchTitle"  *ngIf="showShopRepairUnit">
        <shop-repair-Unit-search
       >
        </shop-repair-Unit-search>

    </collapse-expand-frame> 
</div>



         <div class="row" style="Margin-bottom:20px" *ngIf="showShopRepairUnit">
                <div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 ">
                <div class="form-group">
                    <div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 text-sm-right text-md-right text-right">
                    <button pButton type="button" label="Add Repair Unit" (click)="onAddShopRepair()" class="btn btn-default"></button>
                    <button pButton type="button" label="Search" class="btn btn-default"></button>
                    <button pButton type="button" label="Clear" id="clearSearch" (click)="onClearClick()"  class="btn btn-default"></button>
                    </div>
                </div>
            </div>
              </div>

    <div class="col-lg-12 col-mg-12 col-sm-12 col-xs-12">
    <collapse-expand-frame 
          *ngIf="showAddShopRepairUnit">
        <add-shop-repair-Unit
       >
        </add-shop-repair-Unit>

    </collapse-expand-frame> 
</div>

<div class="col-lg-12 col-mg-12 col-sm-12 col-xs-12">
<collapse-expand-frame 
    [frametitle]="shopRepairUnitSearchResult" *ngIf="showShopRepairUnit">
    <shop-repair-Unit-search-grid 

    >
    </shop-repair-Unit-search-grid >
</collapse-expand-frame>
</div>

<div class="col-lg-12 col-mg-12 col-sm-12 col-xs-12">
<collapse-expand-frame 
    [frametitle]="updateRepairUnitTitle" *ngIf="showShopRepairUnit">
    <update-shop-repair-Unit
    >
    </update-shop-repair-Unit>
</collapse-expand-frame>
</div>
<div class="col-lg-12 col-mg-12 col-sm-12 col-xs-12">
<collapse-expand-frame 
    [frametitle]="missingRepairUnitSearchResult" *ngIf="showMissingRepairUnit">
    <missing-repair-Unit-search-grid 
    >
    </missing-repair-Unit-search-grid>
</collapse-expand-frame>
</div>

最佳答案

我遇到了同样的问题,我将问题追溯到 div 上的 *ngIf 语句

你必须在你的测试中为 'showscooterRepairUnit' 设置一个值,否则它会假设它是 false 并设置 css 元素 null 导致 debugElement 为 null

关于 Angular 4 : Jasmine: Failed: Uncaught (in promise): TypeError: Cannot read property 'nativeElement' of null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44804946/

相关文章:

xml - ruby 单元测试 : Is this a Valid (well-formed) XML Doc?

unit-testing - 无法解析符号: is in this context

java - 在不继承抽象类的情况下模拟对抽象类的公共(public)方法的调用,最好使用 mockito

angular - 测试 Angular Material 表时出现 ExpressionChangedAfterItHasBeenCheckedError

javascript - 如何将代码从 rxjs v5 转换为 rxjs v6 以进行 catch?

angular - 有没有办法从存储为常规 Observable 的数组中返回单个元素?

javascript - AngularJS + Jasmine : Unexpected http calls

angularjs - 使用 Jasmine 刷新成功的模拟 POST 请求不会执行 AngularJS 成功函数

angular - 是否可以将服务注入(inject)到子组件中?

angular - ionic 日期时间选择器动态更新列