Oo'-
Oo'-

Reputation: 236

Angular – Unit test for a subscribe function from a method from an export class in a component

We are using Angular 4.2.4 and are required to write unit tests for it.

We would like to test the subscribe function from a method from an export class and it return false for the showLoading variable. We would like to mock a variable value and test a method called getMotivos.

We also tried these following questions, but unsuccessfully:


export class MotivosCancelamentoComponent implements OnInit {
  showLoading = true;

constructor(
private service: MotivosCancelamentoService,
) { }

  ngOnInit() {
    this.getMotivos();
  }

  getMotivos() {
    this.service.getMotivos().subscribe((data) => {
      this.showLoading = false;
    },
    (error: any) => {
      this.redirectError();
    });
  }
}
describe('MotivosCancelamentoComponent', () => {
  let component: MotivosCancelamentoComponent;
  let service: MotivosCancelamentoService;
  let fixture: ComponentFixture<MotivosCancelamentoComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ MotivosCancelamentoComponent ],
      providers:
      [
        { provide: MotivosCancelamentoService, useValue: motivosCancelamentoServiceStub }
      ]
    })
    .compileComponents();
  }));

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

  it("should call getMotivos and return showLoading value as false", async(() => {
    const showLoading = false;
    spyOn(service, 'getMotivos').and.returnValue(showLoading)
    fixture.detectChanges();
    expect(component.showLoading).toEqual(showLoading);
  }));
});

This last test did not work.

Also give a small look if you ask where MotivosCancelamentoService and motivosCancelamentoServiceStub come from:

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';

export interface Entries {
    entries: any[];
}

const motivos = {
    'entries': [{
        '_version': 1,
    }
    ]
}

@Injectable()
export class MotivosCancelamentoService {

    constructor() { }

    getMotivos(): Observable<object> {
        return of(motivos);
    }

}

export const motivosCancelamentoServiceStub =
{
    getMotivos: ()=> {
        return of(motivos)
    }
}

Upvotes: 0

Views: 1182

Answers (1)

Caio Oliveira
Caio Oliveira

Reputation: 844

You have 2 mistakes there:

  1. If you are testing a method that is called on ngOnInit, your test for "Before Each" will already trigger it as soon as you create the component and detect changes. So you either change your beforeEach, or just call ngOnInit again after your spy.

  2. getMotivos returns observable, so the correct way would be something along these lines

  it("should call getMotivos and return showLoading value as false", () => {
    const showLoading = false;
    spyOn(service, 'getMotivos').and.returnValue(of(showLoading))
    component.ngOnInit();
    fixture.detectChanges();
    expect(component.showLoading).toEqual(showLoading);
  });

Just a side note, it would be better to have the last line as:

    expect(component.showLoading).toEqual(false);
``` Since your component starts with true, and sets to false for any response that returns success

Upvotes: 0

Related Questions