Reputation: 7843
I wish to use Angular's (version 7) TestBed to test a component, and see if an injected service has a method called.
Watching this this tutorial, around 23:18 he show how to create a Jasmine sky, so you can then use test methods such as toHaveBeenCalledTimes
I am trying to do the same thing, except using TestBed
to create the component rather than instantiating manually as in the video.
I have the following..
describe('AppComponent', () => {
beforeEach(async(() => {
fakeStartupService = jasmine.createSpyObj(fakeStartupService, ['start']);
//fakeStartupService.start.and.returnValue(null);
TestBed.configureTestingModule({
imports: [
RouterTestingModule,
],
providers: [
ErrorHandler,
{ provide: StartupService, useValue: fakeStartupService },
],
declarations: [
AppComponent,
],
}).compileComponents();
}));
it('should have called start services start'), () => {
expect(fakeStartupService.start).toHaveBeenCalledTimes(100);
}
});
The first question, is when I type expect(fakeStartupService.
I do not get the code completion to show the start
method as they do in the video.
The other (main) question, is although the above compiles and runs, I don't think I have it correct as the expect(fakeStartupService.start).toHaveBeenCalledTimes(100);
does not fail - the component only calls it once, but I am asserting 100 times, so it should fail.
I took a guess at using the useValue
in the { provide: StartupService, useValue: fakeStartupService },
, so perhaps this is incorrect
I would like to know: is using a spy like this possible, and if so how can I do this?
Actually I had a syntax error (bracket after the description).
The following seems to work for me.
it('should have called start services start once', async () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
// As ngOnInit is async, use detectChanges and whenStable to wait for it to be finished.
fixture.detectChanges();
await fixture.whenStable()
expect(fakeStartupService.start).toHaveBeenCalledTimes(1);
});
Also, to wait for me async ngOnInit
I added the
fixture.detectChanges();
await fixture.whenStable()
Now, the only minor question was how in the video they got the Intellisense.
Upvotes: 0
Views: 1535
Reputation: 18809
I watched part of the video, that is not intellisense/autocomplete. Well, in a way it is, where it is coming from Visual Studio Code and the IDE is matching (and trying its best) what you're typing to what has been typed before in the document. I hope this makes sense.
To get true intellisense and autocomplete in this situation, create an interface somewhere in your project called spied.ts
with the following definition:
export type Spied<T> = {
[Method in keyof T]: jasmine.Spy;
};
Then when you define fakeStartupService
, do it like so:
import { Spied } from './where/spied/type/file/was/saved';
....
let fakeStartupService: Spied<StartupService>;
Now when you type fakeStarupService.st
, autocomplete/intellisense of start
should come up.
I use this and I got this from this article: https://pragmatic-coder.net/typesafe-jasmine-spies/. Scroll down to The fix
.
Upvotes: 1