I've working in an Angular 9 project.
I'm getting a "Expected a spy, but got Function" Error on a test, but only sometimes. Sometimes, all my test pass, other times this one test keeps giving this error.
I'm really confused because it's a pretty simple test, I have other tests in this project that are are essentially the same and never fail. I've also never seen this test fail if I'm focusing on it alone.
Here's my test (that gives an error sometimes):
describe("uploadTemplate", () => {
beforeEach(() => {
fixture = TestBed.createComponent(UploadTemplateComponent);
const mockFile = new File(["mockFile"], "mockPath");
mockFormData.append("document", mockFile);
fixture.detectChanges();
});
it("should show showMessage on error", () => {
let mockError;
const uploadTemplateSpy = spyOn(
mockTemplateService,
"uploadTemplate"
).and.callThrough();
uploadTemplateSpy.and.returnValue(throwError("mock error"));
mockTemplateService.uploadTemplate(mockFormData).subscribe(
() => {},
err => {
mockError = err;
}
);
expect(mockError).not.toBeNull();
spyOn(mockSnackBarService, "showMessage");
component.uploadTemplate();
expect(component.isLoading).toBeFalsy();
expect(mockSnackBarService.showMessage).toHaveBeenCalled();
});
});
As you see, I have mocks for services. Here are my mocks:
export class MockTemplateService {
uploadTemplate(formData: FormData): Observable<Template> {
return of(MockTemplates.templates[0]);
}
}
export class MockSnackBarService {
showMessage() {}
}
and my testBeds:
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [MatSnackBarModule, BrowserAnimationsModule],
providers: [
{ provide: TemplateService, useClass: MockTemplateService },
{
provide: SnackBarService,
useClass: MockSnackBarService
},
{ provide: Router, useClass: MockRouter }
],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [UploadTemplateComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(UploadTemplateComponent);
component = fixture.componentInstance;
mockSnackBarService = TestBed.inject(SnackBarService);
mockTemplateService = TestBed.inject(TemplateService);
fixture.detectChanges();
});
I'm really struggling with finding the cause of this, especially since it never fails when I focus on it. Only sometimes fails when I run all tests, but also if I ignore only the above test, the rest of the tests always seem to pass.
The
spyOnmethod returns a Spy object thattoHaveBeenCalledis expecting, so your code should look something like this: