Arkadi
Arkadi

Reputation: 1357

Angular mock service on component level

I have to mock service methods, which is injected on component level, not on module level. Here's how my component looks like:

@Component({
    selector: 'app-mycomponent',
    template: '<some html content>',
    ...
    providers: [MyService],
})
export class MyComponent implements OnInit {
    constructor(private myService: MyService) {}

    ngOnInit(): void {
        this.myService.myMethod();
    }
}

and my spec file:

define('MyComponent', () => {
    let component: MyComponent;
    let fixture: ComponentFixture<MyComponent>;
    let service: MyService;
    
    beforeEach(waitForAsync(() => {
        TestBed.configureTestingModule({
            imports: [..some modules..],
            providers: [
                { provide: MyService, useClass: MyServiceStub }
            ],
        }).compileComponents();
    }));

    beforeEach(() => {
        fixture = TestBed.createComponent(MyComponent);
        component = fixture.componentInstance;
        service = TestBed.get(MyService);
        fixture.detectChanges();
    });

    it ('should call service method', () => {
        spyOn(service, 'myMethod');

        component.ngOnInit();

        expect(service.myMethod).toHaveBeenCalled();
    });
});

class MyServiceStub {
    myMethod(): void {}
}

When I run npm test, TC fails, complaining that expected method of service wasn't called. it would pass if I provided service on module level, but I need it to be in component level, any idea how to correctly configure spec to work with component level provided service?

Upvotes: 3

Views: 1395

Answers (1)

ChrisY
ChrisY

Reputation: 1783

You can use TestBed.overrideComponent for that.

// Override component's own provider
TestBed.overrideComponent(
   MyComponent,
   {set: {providers: [{provide: MyService, useClass: MyServiceStub}]}}
)
.compileComponents();

See Angular documentation

Upvotes: 5

Related Questions