简体   繁体   中英

Unit testing a Service method subscribed to an Observable in Angular

I want to test this component using Jasmine:

export class EditorComponent implements OnInit {
  movimiento: Movimiento;

  constructor(private route: ActivatedRoute, private datosService: DatosService) { }

  ngOnInit() {
    this.route.params
      .subscribe(params => {
        const _id = params['id'].toString(); // recepción del parámetro
        this.datosService
          .getMovimientoBy_Id$(_id)
          .subscribe(r => this.movimiento = r); // consulta al servicio
      });
  }

}

This methods subscribes to an Observable<Movement> returned by the service. This is the DatosService getMovimientoBy_Id$(_id) method:

getMovimientoBy_Id$(_id): Observable<Movimiento> {
  return this.http
    .get(`priv/movimientos/${_id}`)
    .map(r => r.json());
}

I've tried this code to test the component:

describe('EditorComponent', () => {
  let movimiento = new Movimiento(new Date(), 0, 1, 1);
  let component: EditorComponent;
  let fixture: ComponentFixture<EditorComponent>;
  let datosService: DatosService;

  beforeEach(async(() => {
    let activatedRouteMock = {
      route: Observable.of({ id: 1 })
    }

    TestBed.configureTestingModule({
      imports: [
        HttpModule
      ],
      declarations: [
        EditorComponent
      ],
      providers: [
        DatosService,
        { provide: ActivatedRoute, useValue: activatedRouteMock }
      ]
    })
      .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(EditorComponent);
    component = fixture.componentInstance;
    datosService = fixture.debugElement.injector.get(DatosService);
  });

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

  it('should create movimiento', (done) => {
    let spy = spyOn(datosService, 'getMovimientoBy_Id$').and.returnValue(Observable.of(movimiento));
    fixture.detectChanges();
    expect(component.movimiento).toBeTruthy();
    });
});

The first test passes, but in the second I'm getting this exception

Uncaught Error: Error in :0:0 caused by: Cannot read property 'subscribe' of undefined

I don't understand what I'm doing wrong... Any ideas on what's going on? Thanks.

Angular cli stopped adding second before each.

 beforeEach(() => {
    fixture = TestBed.createComponent(EditorComponent);
    component = fixture.componentInstance;
    datosService = fixture.debugElement.injector.get(DatosService);
  });

This make sense since you usually want to mock data before you start testing.

But you actual problem is how you mock router. You need to add to route property params otherwise params is null

Try following:

describe('EditorComponent', () => {
  let movimiento = new Movimiento(new Date(), 0, 1, 1);


beforeEach(async(() => {
    let activatedRouteMock = {
      route: {
        params: {
          Observable.of({ id: 1 })
        }
      }
    }

    TestBed.configureTestingModule({
      imports: [
        HttpModule
      ],
      declarations: [
        EditorComponent
      ],
      providers: [
        DatosService,
        { provide: ActivatedRoute, useValue: activatedRouteMock }
      ]
    })
      .compileComponents();
  }));

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

  it('should create movimiento', (done) => {
    var datosService = TestBed.get(DatosService);
    let spy = spyOn(datosService, 'getMovimientoBy_Id$').and.returnValue(Observable.of(movimiento));

    var fixture = TestBed.createComponent(EditorComponent);
    var component = fixture.componentInstance;
    fixture.detectChanges();
    expect(component.movimiento).toBeTruthy();
  });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM