Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 Jasmine SpyOn Method Does Not Exist

I have defined an interface and opaque token as follows

export let AUTH_SERVICE = new OpaqueToken('auth.service');

export interface AuthService {
    logIn(): void;
    logOut(): void;
}

In my test class I provide a stubbed version of AuthService, i.e.,

@Injectable()
class AuthServiceStub implements AuthService {
    logIn(): void {}
    logOut(): void {}
}

and set up my test beforeEach as follows

beforeEach(async(() => {
        TestBed.configureTestingModule({
            declarations: [ LoginComponent ],
            providers: [
                {provide: AUTH_SERVICE, useValue: AuthServiceStub}
            ]
        });
    }));

I then started to write the test, i.e.,

it('should call log in on AuthService', () => {
        let authService = fixture.debugElement.injector.get(AUTH_SERVICE);
        spyOn(authService, 'logIn');
        // expect will go here
});

but I get the following error

 Error: <spyOn> : logIn() method does not exist

Can't see what I'm doing wrong. Any ideas?

like image 957
James B Avatar asked Feb 22 '17 20:02

James B


Video Answer


1 Answers

That's because you're using useValue property in the provider object. That means the injected value will be the AuthServiceStub class itself. What you want instead, is its instance that actually have those methods.

To make the test works, replace useValue with useClass. This will make the Angular's dependency injection system to actually instantiate the service when the provider is created and your call fixture.debugElement.injector.get(AUTH_SERVICE); will return a proper object.

Alternatively you could instantiate the class manually:

it('should call log in on AuthService', () => {
    let AuthService = fixture.debugElement.injector.get(AUTH_SERVICE);
    let authService = new AuthService();
    spyOn(authService, 'logIn');
    // expect will go here
});

Still, useClass is a better solution, since it will handle all future injections that the AuthService might need.

like image 97
Mateusz Kocz Avatar answered Sep 18 '22 17:09

Mateusz Kocz