Reputation: 23487
I have the following code...
export class LoginComponent {
userName: string;
password: string;
rememberMe: boolean = false;
constructor( private auth: AuthenticationService,
private router: Router) {
...
}
...
}
I am trying to Unit test but my first attempt failed....
beforeEach(() => {
router = new Router();
component = new LoginComponent(authService, router);
});
Because it needs the params for the Router constructor. Here I saw...
beforeEach(() => addProviders([
APP_ROUTER_PROVIDERS, // must be first
{provide: APP_BASE_HREF, useValue: '/'}, // must be second
{provide: ActivatedRoute, useClass: Mock},
{provide: Router, useClass: Mock}
]));
But I don't seem to have APP_ROUTER_PROVIDERS
or Mock
anywhere in my dependencies, so I think it might be stale (or I need dependencies).
How do I mock this out? It doesn't even matter for the test I am working on.
Upvotes: 9
Views: 6037
Reputation: 24775
Here is a working example of loading query string parameters for each test. Works on Angular 2.3.
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
MyViewerComponent,
...
],
imports: [
HttpModule,
FormsModule,
RouterModule,
...
],
providers: [
{provide: ActivatedRoute, useValue: {queryParams: {test: 111}}},
{provide: MyService, useClass: MyMockService}
]
})
.compileComponents();
}));
Upvotes: 3
Reputation: 23487
I accepted the above answer because it appears to be correct, however, I actually implemented it differently...
describe("Login Component", () => {
let component: LoginComponent;
let authService: AuthenticationService;
let router: Router;
describe("Testing the subscription happens", () => {
beforeEach(() => {
TestBed.configureTestingModule({imports: [RouterTestingModule]});
router = TestBed.get(Router);
authService = new AuthenticationService();
authService.notifications = new Subject();
authService.notifications.subscribe = jasmine.createSpy("SpyToTestNotifications");
});
it("Make sure we try to subscribe to the auth event", () => {
component = new LoginComponent(authService, router);
expect(authService.notifications.subscribe).toHaveBeenCalled();
})
});
});
As you can see this only requires 2 lines in the beforeEach...
TestBed.configureTestingModule({imports: [RouterTestingModule]});
router = TestBed.get(Router);
However, per @jonrsharpe this does a lot of things so you can't guarantee what other side effects might happen. But it is quick, it is dirty and it does seem to "work"
Upvotes: 2
Reputation: 121966
For a simple case you could just create your own mock and provide it by value, for example:
describe('whatever', () => {
let mockRouter: any;
...
beforeEach(async(() => {
// create your own mock
mockRouter = jasmine.createSpyObj('Router', ['navigate']);
...
TestBed.configureTestingModule({
declarations: [LoginComponent],
providers: [
// provide it by value
{ provide: Router, useValue: mockRouter },
...
],
}).compileComponents();
}));
...
});
This uses the test bed's dependency injection, rather than trying to "new
-up" the class under test.
For an example in context, see e.g. one of my projects on GitHub.
Upvotes: 10