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:
- Angular - unit test for a subscribe function in a component
- Unit test for a subscribe function
- failed to run unit test for component that extends a base class in angular
- Test that a method in an Angular component called subscribe
- How to mock a response from an Angular service in a unit test
- Angular UNIT Testing method with .subscribe misunderstanding
motivos-cancelamento.component.ts, a component that I want to test:
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();
});
}
}
motivos-cancelamentp.component.spec.ts, a unit test, where I tried to test.
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:
motivos-cancelamento.service.ts:
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)
}
}
You have 2 mistakes there:
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.
getMotivos returns observable, so the correct way would be something along these lines
Just a side note, it would be better to have the last line as: