Unit test issue when using LoadingController


#1

Hi, I’m using the LoadingController to show a message when retrieving some data, which works fine, but when I run my unit tests I get TypeError: controller.componentOnReady is not a function. I know it’s related to the LoadingController, because if I remove it from the page, the tests run fine. I did think it was because the LoadingController uses a Promise which I wasn’t fulfilling, but when I added the then statement to the LoadingController call the test still fails.

this is how I implemented the Loader:

 this.loader
            .create({ spinner: 'hide', message: 'Loading Messages' })
            .then(() => {
                console.log('Loading');
            });

I’m not sure what the error message is trying to tell me? Can anyone shed some light on this?

Thanks,

Stephen


#2

Actually I’ve found out what the problem was. I needed to mock up the create and dismiss functions in my Provider for the test, like this:

 providers: [
                MessageService,
                {
                    provide: LoadingController,
                    useValue: {
                        create: () => Promise.resolve(),
                        dismiss: () => Promise.resolve()
                    }
                }
            ]

The create and dismiss functions never completed because they return Promises, but failed due to the test not creating the Overlay you’d expect to see when the loader is running.


#3

Hey, I’m getting the exact same error. Unfortunately, adding the loadingcontroller to the provider to resolve the promises doesn’t seem to work for me. Do you perhaps know if I may be missing something?

Thanks,

Wesley


#4

Hey Wesley,

Does your component have other dependencies? These might need to be mocked as well.

Stephen


#5

Hey, Thanks for replying. I don’t think I’ve got other dependencies. When I went to debugging I noticed that my test didn’t seem to use the mocked create function. Promise.resolve() was never called.

This is the code I’m using for my loader:

  async presentLoader(duration?: number) {
    this.loading = await this.loadingController.create({
      spinner: 'crescent',
      message: this.translate.instant('generic.feedback.loading'),
      duration: duration,
      cssClass: 'custom-loader',
    });

    return await this.loading.present();
  }

  dismissLoader() {
    this.loading.dismiss().then();
  }

And I’ve mocked the LoadingController in the service.spec.ts where the above code is located. I’m getting the error from Karma in a different spec file though. The strange thing is, I’m only getting the error on my ‘JobsPage’ even though I’ve imported the service with the LoadingController in all my pages.

Karma error:

Uncaught Error: Uncaught (in promise): TypeError: controller.componentOnReady is not a function
TypeError: controller.componentOnReady is not a function
    at proxyMethod (http://localhost:9876/node_modules/@ionic/angular/dist/fesm5.js?:4339:1)
    at LoadingController.push../node_modules/@ionic/angular/dist/fesm5.js.OverlayBaseController.create (http://localhost:9876/node_modules/@ionic/angular/dist/fesm5.js?:4384:1)
    at SharedService.<anonymous> (http://localhost:9876/src/app/services/shared.service.ts?:64:49)
    at step (http://localhost:9876/_karma_webpack_/main.js:2872:23)
    at Object.next (http://localhost:9876/_karma_webpack_/main.js:2853:53)
    at http://localhost:9876/_karma_webpack_/main.js:2847:71
    at new ZoneAwarePromise (http://localhost:9876/node_modules/zone.js/dist/zone.js?:910:1)
    at ./src/app/services/shared.service.ts.__awaiter (http://localhost:9876/_karma_webpack_/main.js:2843:12)
    at SharedService../src/app/services/shared.service.ts.SharedService.presentLoader (http://localhost:9876/_karma_webpack_/main.js:2953:16)
    at FlexplaatsingenService.<anonymous> (http://localhost:9876/src/app/services/flexplaatsingen.service.ts?:23:23) thrown

#6

Can you add your test code here? Do you know what the ‘controller’ it is referencing?


#7

Hey Stephan, Thanks for your help but I seem to have (accidentally) fixed the problem. I had the call to the LoadingController in another service. When I moved the call from that service to a page, the problem stopped. Now I don’t even need the LoadingController in the provider of my test. I have no idea why this works and the old situation doesn’t. If you happen to know, please let me know.

Thanks again for your help!