Ionic + Jasmine + Tslint - Property 'and' does not exist on type
Asked Answered
A

2

8

everybody. I am building an Ionic app over this boilerplate. Right now, I am building the tests for a specific page and I am using jasmine to mock the providers and set the expected behavior for the methods. That's how the beforeEach() method looks like looks like:

    beforeEach(() => {
          mockLoadingController = jasmine.createSpyObj('ModalController', ['create', 'present', 'dismiss']);
          mockLoadingController.create.and.returnValue(mockLoadingController);

          mockModalController =  jasmine.createSpyObj('LoadingController', ['create', 'present',
            'onDidDismiss', 'dismiss']);
          mockModalController.create.and.returnValue(mockModalController);

          mockGeolocation =  jasmine.createSpyObj('Geolocation', ['getCurrentPosition']);

          mockGeolocation.getCurrentPosition.and.callFake(( ) => {
            return {then: ( ) => { }};
          });
          mockEvents = jasmine.createSpyObj('Events', ['publish', 'subscribe']);
          TestBed.configureTestingModule({
            schemas: [CUSTOM_ELEMENTS_SCHEMA],
            providers: [
              { provide: NavController, useValue: mockNavController },
              { provide: LoadingController, useValue: mockLoadingController },
              { provide: ModalController, useValue: mockModalController },
              { provide: Geolocation, useValue: mockGeolocation },
              { provide: Events, useValue: mockEvents },
              LocationPage,
            ],
          },
    ); } );

The problem starts when I define the promise return for the getCurrentPosition method:

    mockGeolocation.getCurrentPosition.and.callFake(( ) => {
            return {then: ( ) => { }};
    });

I am using tslint while testing and, it gives me the following error

ERROR in [at-loader] ./src/pages/location/location.page.spec.ts:24:40 
    TS2339: Property 'and' does not exist on type '(options?: GeolocationOptions) => Promise<Geoposition>'.

The question is: how can I overcame this matter so TSLint does not complain about this code anymore?

Awake answered 7/4, 2017 at 14:29 Comment(1)
It seems your problem is not with tslint. Your code mockGeolocation.getCurrentPosition.and.callFake is wrong. I think it need to be something like: mockGeolocation.create.and.getCurrentPosition..... Take a look at the pattern for the other mocks (e.g. mockModalController)Garvey
R
16

Actually proper types will be:

  let mockGeolocation: jasmine.SpyObj<Geolocation>;
  let mockEvents: jasmine.SpyObj<Events>;

Richerson answered 27/3, 2019 at 21:52 Comment(1)
Thanks fot the precise details! Indeed it worked like this.Gaffrigged
A
8

Problem solved! I forgot to detail the way I was declaring the variables:

describe('Location Page', () => {
  let mockLoadingController: any;
  let mockModalController: any;
  let mockGeolocation: Geolocation;
  let mockEvents: Events;
  beforeEach(() => {
  //rest of the code here

As you can see, I defined a type to the mockGeolocation variable and I did set the others as any. Setting all the variables as any works perfectly with jasmine and it does not generate an error in tslint.

So the correct code works like this:

describe('Location Page', () => {
  let mockLoadingController: any;
  let mockModalController: any;
  let mockGeolocation: any;
  let mockEvents: any;
  beforeEach(() => {
Awake answered 7/4, 2017 at 18:24 Comment(2)
Oh, Man! Thank you very much! It was exactly my problem.Gaffrigged
Setting the type to any is never the correct solution. It may be a work-around but it's definitely not correct. All that is doing is bypassing the type system.Johore

© 2022 - 2024 — McMap. All rights reserved.