I am having trouble testing a service injected into an Angular component.
Here is an example scenario I am facing. Let's say I have SampleComponent
that has SampleService
injected. I want to test whether running handleAction()
in SampleComponent
calls SampleService.doSomething()
.
@Component({
...
})
export class SampleComponent {
constructor(private sampleService: SampleService) { }
handleAction(): void {
this.sampleService.doSomething();
}
}
import { SampleComponent } from './sample.component';
import { waitForAsync } from "@angular/core/testing";
import { createComponentFactory, Spectator } from "@ngneat/spectator";
describe('SampleComponent', () => {
let spectator: Spectator<SampleComponent>;
let component: SampleComponent;
const createComponent = createComponentFactory({
component: SampleComponent,
imports: [ CommonModule ],
declarations: [ SampleComponent ],
mocks: [ SampleService ]
});
beforeEach(waitForAsync(() => {
spectator = createComponent();
component = spectator.component;
}));
it("should call SampleService.doSomething", () => {
const sampleService = spectator.inject(SampleService);
const spySampleServiceFunction = spyOn(sampleService, "doSomething").and.callThrough();
component.handleAction();
expect(spySampleServiceFunction).toHaveBeenCalled();
});
});
Regardless of whether I use and.callThrough()
for spyObject or not, I get the following error.
Error: <spyOn>: doSomething has already been spied upon
// same until 'it'
it("should call SampleService.doSomething", () => {
const sampleService = spectator.inject(SampleService);
component.handleAction();
expect(sampleService.doSomething).toHaveBeenCalled();
});
I get the following error.
TypeError: Cannot read properties of undefined (reading 'doSomething')
If I put SampleService
in providers
, errors are caused due to the dependencies injected to SampleService
.
Any sort of advice and suggestions would be appreciated!
Actually on the second look, the code was getting the service as an Input
not a dependency, so that was why the test wasn't working. But, I'll post the final code anyways.
import { SampleComponent } from './sample.component';
import { waitForAsync } from "@angular/core/testing";
import { createComponentFactory, Spectator, SpyObject } from "@ngneat/spectator";
describe('SampleComponent', () => {
let spectator: Spectator<SampleComponent>;
let component: SampleComponent;
let sampleService: SpyObject<SampleService>;
const createComponent = createComponentFactory({
component: SampleComponent,
imports: [ CommonModule ],
declarations: [ SampleComponent ],
mocks: [ SampleService ]
});
beforeEach(waitForAsync(() => {
spectator = createComponent();
component = spectator.component;
sampleService = spectator.inject(SampleService);
sampleService.doSomething.and.callThrough();
spectator.detectChanges();
}));
it("should call SampleService.doSomething", () => {
component.handleAction();
expect(spySampleServiceFunction).toHaveBeenCalled();
});
});