JavaEar 专注于收集分享传播有价值的技术资料

Cannot read property 'length' of null + "angular"?

I am trying to count initial li and after fetching data from server (using unit test case), but I am getting Cannot read property 'length' of null

My code:

import { ComponentFixture, TestBed, async, getTestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';

import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { HttpClientModule, HttpClient } from '@angular/common/http';
import { MockAppService } from './mock.service'
import { DebugElement } from '@angular/core';

import { AppComponent } from './app.component';
import { AppService } from './app.service';

describe('AppComponent', () => {
  let fixture: ComponentFixture<AppComponent>,
    component: AppComponent,
    service: AppService,
    debugEl:DebugElement,
    el:HTMLElement;
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule],
      declarations: [
        AppComponent
      ],

      providers: [{ provide: AppService, useClass: MockAppService }]

    }).compileComponents();

    fixture = TestBed.createComponent(AppComponent);
    component = fixture.componentInstance;
    service = TestBed.get(AppService);
     el = fixture.nativeElement;

    spyOn(service, 'getData').and.callThrough();

  }));

  afterEach(() => {
    //httpMock.verify();
  });

  describe('AppComponent onit test', () => {

        it('intial list item', async(() => {
                  debugEl = fixture.debugElement.query(By.css('li'));
      expect(fixture.nativeElement.querySelector('li').length()).toBe(0);
    }));
    it('should called appService getData method', async(() => {
      fixture.detectChanges();
      expect(service.getData).toHaveBeenCalled();
    }));
    it('should return an Observable<User[]>', () => {
      const dummyUsers = [{
        userId: 10,
        id: 10,
        title: "post",
        body: "post"
      }];

      service.getData().subscribe(users => {
        console.log(users)
        expect(users.length).toBe(1);
        expect(users).toEqual(dummyUsers);
         expect(fixture.nativeElement.querySelector('li').length()).toBe(1);

      });
    });
  })
});

code link

https://stackblitz.com/edit/angular-testing-w9towo?file=app%2Fapp.component.spec.ts

enter image description here

2个回答

    最佳答案
  1. query does not return an array, try to use queryAll to return an array instead of query here is the solution:

    it('intial list item', async(() => {
       let liCount= fixture.debugElement.queryAll(By.css('li'));
       expect(liCount.length).toBe(0);
    }));
    
  2. 参考答案2
  3. When you look at this documentation: https://angular.io/api/core/DebugElement

    You will find that DebugElement.query method returns DebugElement

    and the method DebugElement.queryAll method returns DebugElement[]

    so DebugElement.queryAll will return an array of DebugElement

    and in this case, since it's an array you can then apply length property to it.

    So you have to use DebugElement.queryAll in order to test the length of the resulting array.