Reputation: 31
I'm having trouble unit testing with NavController.
I'm stuck at this error:
Cannot resolve all parameters for 'NavController'(?, ?, ?, ?, ?, ?, ?, ?). Make sure that all the parameters are decorated with Inject or have valid type annotations and that 'NavController' is decorated with Injectable.
I tried everything I found on the net, like using '@Inject', and nothing seems to work.
Here is the code:
Component
import {Page, MenuController, NavController} from 'ionic-angular';
import {SignupPage} from '../signup/signup';
@Page({
templateUrl: 'build/pages/welcome/welcome.html'
})
export class WelcomePage {
// Variables
constructor(private menu: MenuController, private nav: NavController) {
this.menu.enable(false);
}
goToSignupPage() {
this.nav.push(SignupPage)
}
}
Unit test
import {beforeEachProviders, it, describe, expect, inject} from '@angular/core/testing';
import {MenuController, NavController} from 'ionic-angular';
import {WelcomePage} from './welcome';
describe('WelcomePage', () => {
beforeEachProviders(() => [WelcomePage, MenuController, NavController]);
it('should have the menu disabled on instatiation', inject([WelcomePage], (welcomePage) => {
// Expectations
expect(welcomePage.menu.isEnabled()).toBeFalsy();
}));
});
Any idea whats wrong?
UPDATE:
Thanks for the replies, guys.
It really helped me to understand how to do it.
I didn't use sinon
, but I was able to test if the push
was called
using the spyOn
from Jasmine.
For that, I did a subtle change to the provide
part:
beforeEachProviders(() => [WelcomePage, MenuController,
{ provide: NavController, useValue: {push: NavController.prototype.push} }]);
(Probably it would be nice to serve the NavController.prototype
directly to have access to all the other properties.)
And then tested like this:
it('should go to signup page when calling goToSignupPage()',
inject([WelcomePage], (welcomePage) => {
// Spies
spyOn(welcomePage.nav, 'push').and.stub();
// Call
welcomePage.goToSignupPage();
// Expectations
expect(welcomePage.nav.push).toHaveBeenCalledWith(SignupPage);
}));
Upvotes: 3
Views: 2075
Reputation: 25
As GoldBones, the problem is that the NavController that has been imported is a class not a provider, so you need to define your own provider. The provide(...)
syntax is deprecated, but the final code is pretty similar to the old syntax:
beforeEachProviders(() => [WelcomePage, MenuController, {provide: NavController, useValue: {} }]);
I've used an empty object above, but as WelcomePage uses the push
method, you will need to stub this out with something like:
let stubNavController = {push: (page) => {}};
beforeEachProviders(() => [WelcomePage, MenuController, {provide: NavController, useValue: stubNavController }]);
Using a spying library like Sinon could be useful here if you want to test that the method was called.
Upvotes: 1
Reputation: 1457
Try this on your Unit Test class:
beforeEachProviders(() => [WelcomePage, MenuController, provide(NavController, { useValue: WelcomePage })]);
and then:
import {provide} from '@angular/core';
Upvotes: 3