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.
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.
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();
}));
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"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With