I have following test. It fails and appears that the spyOn is not mocking the service correctly or may be I don't understand it. I put a console in the component method and could see it when test runs, shouldn't the actual method be not called when I am spying on it? I thought may be it's due to api taking sometime, so tried fakeAsync
, flush
and tick
etc. but none worked.
describe('AppComponent', () => {
let service: any;
let fixture: ComponentFixture<AppComponent>;
let component: AppComponent;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [RouterTestingModule, HttpClientTestingModule],
declarations: [AppComponent],
providers: [PatientdataService],
}).compileComponents();
service = TestBed.inject(PatientdataService);
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
});
it('should call getPatient from service', () => {
const dataSpy = spyOn(component, 'loadPatientData');
const patientSpy = spyOn(service, 'getPatientValues').and.returnValue(of([]));
const medSpy = spyOn(service, 'getMedicationValues').and.returnValue(of([]));
component.getPatientDetails();
expect(dataSpy).toHaveBeenCalledTimes(1);
expect(patientSpy).toHaveBeenCalledTimes(1);
expect(medSpy).toHaveBeenCalledTimes(1);
});
});
Following is the component method it's trying to test -
getPatientDetails() {
this.service.getPatientValues().subscribe({
next: (data) => {
this.loadPatientData(JSON.parse(data));
this.service.getMedicationValues().subscribe({
next: (data) => {
this.loadMedicationData(JSON.parse(data));
this.service.getConditionsValues().subscribe({
next: (data) => {
...
...
This is the error I get -
Error: Expected spy loadPatientData to have been called once. It was called 0 times.
at <Jasmine>
at UserContext.<anonymous> (src/app/app.component.spec.ts:41:21)
at _ZoneDelegate.invoke (node_modules/zone.js/fesm2015/zone.js:372:1)
at ProxyZoneSpec.onInvoke (node_modules/zone.js/fesm2015/zone-testing.js:287:1)
Error: Expected spy getMedicationValues to have been called once. It was called 0 times.
at <Jasmine>
at UserContext.<anonymous> (src/app/app.component.spec.ts:43:20)
at _ZoneDelegate.invoke (node_modules/zone.js/fesm2015/zone.js:372:1)
at ProxyZoneSpec.onInvoke (node_modules/zone.js/fesm2015/zone-testing.js:287:1)
CodePudding user response:
If you try to parse JSON that isn't valid you'll get runtime exception Unexpected end of JSON input
, I suspect that's what's happening here
// You're returning of([])
// So data is [], which isn't valid
// for JSON.parse
this.loadPatientData(JSON.parse(data))
If this is how your code should behave, and isn't a mistake, then try using of(JSON.stringify([]))
The reason the code is invoked is because you use returnValue
for getPatientValues
- if you don't use that then the function won't be invoked - but none of the other functions would be called after that either