"Expected spy on mockLogin.getToken to equal true." is the error showing up - unit-testing

What I am trying to do is get access to my return value of the mockLoginService.getToken and check if it is equal to true. How can I achieve that?
import { async, ComponentFixture, TestBed, waitForAsync } from '#angular/core/testing';
import { FormsModule } from '#angular/forms';
import { RouterTestingModule } from '#angular/router/testing';
import { TranslateModule } from '#ngx-translate/core';
import { AppMetadataHandler } from 'app/BaseFramework/configs';
import { AuthenticationService, LoginService } from 'app/BaseFramework/core';
import { ThreadsService } from 'app/BaseFramework/core/utilities/threads.service';
import { NgZorroAntdModule } from 'app/ng-zorro.module';
import { AsyncSubject, of } from 'rxjs';
import { LoginComponent } from './login.component';
describe('LoginComponent', () => {
let component: LoginComponent;
let fixture: ComponentFixture<LoginComponent>;
const mockDb={username:'admin',password:'admin'}
let mockAuthenticationService;
let mockAppMetadataHandler;
// const mockThreadsService= jasmine.createSpyObj<ThreadsService>(['PRELOGINTHREAD'])
let mockLoginService;
beforeEach(waitForAsync(() => {
mockLoginService=jasmine.createSpyObj<LoginService>('mockLogin',['getToken']);
mockAppMetadataHandler = jasmine.createSpyObj\<AppMetadataHandler>(['getEntryPoint','featureFlags']);
mockAuthenticationService = jasmine.createSpyObj<AuthenticationService>(['logout','fetchToken'])
TestBed.configureTestingModule({
declarations: [ LoginComponent ],
providers:[
{provide:AuthenticationService,useValue:mockAuthenticationService },
{provide:AppMetadataHandler,useValue: mockAppMetadataHandler},
{provide:ThreadsService,useValue: {
PRELOGINTHREAD: () => of([1,2,3]),
_errorThreadLog:()=>of('')
}}
],
imports:[NgZorroAntdModule, RouterTestingModule,TranslateModule.forRoot(),FormsModule,]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(LoginComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('Should be Login Successful if success is true ', () => {
component.loginContext={username:'admin',password:'admin'}
expect(component.loginContext).toEqual(mockDb)
let returnval = mockLoginService.getToken.and.returnValue(of(true));
expect(returnval).toEqual(true)
});
});
Angular CLI: 12.2.18
Node: 14.17.3
Package Manager: npm 6.14.13
OS: win32 x64
Angular: 12.2.17

Related

Jasmine/karma test case are not running in an orderly manner using Angular5

When running the test case using jasmine/karma test cases. I am facing n issue which is before starting with the Login spec test case the other spec files are all called before completing the Login. It need to happen in an orderly manner which is like
1.Login
2.Dashboard
3.Order
etc.
Is there a way to do this.
login.spec.ts file
import { async, ComponentFixture, TestBed } from '#angular/core/testing';
import { RouterModule, Router } from '#angular/router';
import { LoginComponent } from './login.component';
import { DebugElement } from '#angular/core';
import { FormsModule, ReactiveFormsModule } from '#angular/forms';
import { BrowserModule, By } from '#angular/platform-browser';
import { Ng2Bs3ModalModule } from 'ng2-bs3-modal/ng2-bs3-modal';
import { RouterTestingModule } from '#angular/router/testing';
import { APP_BASE_HREF } from '#angular/common';
import { LoginService } from './login.service';
import { HttpClientModule } from '#angular/common/http';
import { ApiService } from '../config/api.service';
import { ConfigService } from '../config/config.service';
import { Constants } from '../config/Constant';
import { SharedService } from '../shared/shared.service';
import { Http, BaseRequestOptions, ResponseOptions, Response, RequestMethod } from '#angular/http';
import { inject } from '#angular/core/testing';
import { MockBackend, MockConnection } from '#angular/http/testing';
describe('LoginComponent', () => {
let comp: LoginComponent;
let fixture: ComponentFixture<LoginComponent>;
let de: DebugElement;
let el: HTMLElement;
let userNameEl: DebugElement;
let passwordEl: DebugElement;
let submitEl: DebugElement;
let loginService: LoginService = null;
let backend: MockBackend = null;
TestBed.overrideComponent(LoginComponent, {
set: {
providers: [
{
provide: LoginService,
useValue: loginService
},
{
provide: Router,
useClass: class { navigate = jasmine.createSpy('navigate'); }
}
]
}
});
beforeEach(async(() => {
// loginService = loginService;
// backend = mockBackend;
TestBed.configureTestingModule({
declarations: [
LoginComponent
],
imports: [
RouterModule.forRoot([{
path: '',
component: LoginComponent
}]),
BrowserModule,
FormsModule,
ReactiveFormsModule,
Ng2Bs3ModalModule,
RouterTestingModule,
HttpClientModule
],
providers: [
MockBackend,
BaseRequestOptions,
{
provide: Http,
useFactory: (backendInstance: MockBackend, defaultOptions: BaseRequestOptions) => {
return new Http(backendInstance, defaultOptions);
},
deps: [MockBackend, BaseRequestOptions]
},
LoginService,
ApiService,
ConfigService,
Constants,
SharedService,
{ provide: APP_BASE_HREF, useValue: '/' }
]
}).compileComponents().then(() => {
fixture = TestBed.createComponent(LoginComponent);
comp = fixture.componentInstance;
de = fixture.debugElement.query(By.css('form'));
el = de.nativeElement;
userNameEl = fixture.debugElement.query(By.css('input[id=InputEmail1]'));
passwordEl = fixture.debugElement.query(By.css('input[id=InputPassword1]'));
submitEl = fixture.debugElement.query(By.css('.login-btn'));
});
}));
beforeEach(inject([LoginService, MockBackend], (Service: LoginService, mockBackend: MockBackend) => {
loginService = Service;
backend = mockBackend;
}));
it('should create', () => {
expect(comp).toBeTruthy();
});
it('To check the initial value', () => {
expect(comp.submitted).toBe(false);
expect(comp.spinnerlogo).toBeFalsy();
expect(comp.data).toEqual({});
});
it(`entering value in username and password input controls`, () => {
userNameEl.nativeElement.value = 'admin';
passwordEl.nativeElement.value = 'admin';
fixture.detectChanges();
});
it('after entering value the button should enabled and click Action should happen', () => {
expect(submitEl.nativeElement.disabled).toBeFalsy();
const loginButtonSpy = spyOn(comp, 'onSubmit');
submitEl.triggerEventHandler('click', null);
expect(loginButtonSpy).toHaveBeenCalled();
});
it('calling onSubmit method after clicked the login button', () => {
comp.submitted = true;
comp.spinnerlogo = true;
comp.errorDiagnostic = null;
comp.mailerrorDiagnostic = null;
expect(comp.submitted).toBeTruthy();
expect(comp.spinnerlogo).toBeTruthy();
expect(comp.errorDiagnostic).toBeNull();
expect(comp.mailerrorDiagnostic).toBeNull();
});
it('#login should call endpoint and return it\'s result', (done) => {
backend.connections.subscribe((connection: MockConnection) => {
const options = new ResponseOptions({
body: JSON.stringify({ success: true })
});
connection.mockRespond(new Response(options));
// Check the request method
expect(connection.request.method).toEqual(RequestMethod.Post);
// Check the url
expect(connection.request.url).toEqual('/auth/login');
// Check the body
// expect(connection.request.text())
expect(connection.request.text()).toEqual(JSON.stringify({ username: 'admin', password: 'admin' }));
// Check the request headers
expect(connection.request.headers.get('Content-Type')).toEqual('application/json');
});
loginService.login('admin', 'admin')
.subscribe((response) => {
console.log('response values are ---####------------ ', response);
// Check the response
expect(response.user.username).toEqual('admin');
expect(response.user.password).toEqual('admin');
// set value in sessionStorage
sessionStorage.setItem('currentUser', JSON.stringify(response));
sessionStorage.setItem('token', JSON.stringify(response.token));
sessionStorage.setItem('dismissOrders', 'false');
done();
},
(error) => {
expect(error).toThrowError();
});
});
});
the main problem is before executing the above file . The other spec file are executed
Thanks,
Kishan

jasmine test cases dependency in angular 2 with stub

Here I'm new to angular 2 test cases with jasmine + karma and I'm following this testing guide I tried to write test case but unable to write correctly and getting routing error as test cases are going to server while running, although it should not.
There is a question similar to this but didn't help me to solve the problem. Please guide me.
Here is my component
import { Component, OnInit, ViewChild } from '#angular/core';
import { Router, ActivatedRoute } from '#angular/router';
import { Checklist } from './checklist';
import { Job } from '../+job/job';
import { OriginalService } from './original.service';
import { UserService } from '../core/user/user.service';
import { ModalDirective } from 'ng2-bootstrap/ng2-bootstrap';
#Component({
selector: 'app-selector',
templateUrl: './original.component.html',
providers: [OriginalService]
})
export class OriginalComponent implements OnInit {
items = []
job: Job;
checklist: Checklist;
user: any;
shopId: any;
jobId: any;
constructor ( private orgService: OriginalService, private route: ActivatedRoute, private router: Router, userService: UserService) {
this.user = userService.user();
}
ngOnInit() {
this.route.params
.map(params => params['job_id'])
.subscribe(
job_id => this.jobId = job_id
);
this.getChecklist();
this.getJob();
}
getChecklist() {
this.orgService.getChecklists({
jobId: this.jobId
})
.then(checklist=> {
this.gotJobdata = true;
this.checklist = checklist.response})
.catch(error => this.error = error);
}
getJob(){
this.orgService.getJob({
jobId: this.jobId
})
.then(job => this.job = job.response)
.catch(error => this.error = error);
}
}
Here's my service
import { Injectable, ViewChildren } from '#angular/core';
import { Http, Response, Headers, RequestOptions } from '#angular/http';
import { environment } from '../../environments/environment'
import 'rxjs/add/operator/toPromise';
import { Checklist } from './checklist';
import { Job } from '../+job/job';
import { UserService } from '../core/user/user.service';
#Injectable()
export class OriginalService {
shopId: any;
constructor(private http: Http, private userService: UserService ) {
this.shopId = userService.shopId();
}
getChecklists(svc): Promise<Checklist> {
return this.http.get(environment.apiUrl + this.shopId + '/jobs/' + svc.jobId + '/checklists_path/' + 'check_item.json')
.toPromise()
.then(response => response.json())
.catch(this.handleError);
}
getJob(svc): Promise<Job> {
return this.http.get(return environment.apiUrl + this.shopId + '/jobs/' + svc.jobId + '.json')
.toPromise()
.then(response => response.json())
.catch(this.handleError);
}
}
Here's the spec what I've tried:
import { async, ComponentFixture, TestBed } from '#angular/core/testing';
import { SharedModule } from '../shared/shared.module';
import { ModalModule } from 'ng2-bootstrap/ng2-bootstrap';
import { HttpModule } from '#angular/http';
import { Router, ActivatedRoute, Params } from '#angular/router';
import { ComponentLoaderFactory } from 'ng2-bootstrap/component-loader';
import { Subject } from 'rxjs/Subject';
import { UserService } from '../core/user/user.service';
import { OriginalService } from './original.service';
import { OriginalComponent } from './original.component';
describe('OriginalComponent', () => {
let component: OriginalComponent;
let fixture: ComponentFixture<OriginalComponent>;
let params: Subject<Params>;
let userService, orgService;
let userServiceStub = {
isLoggedIn: true,
user: { name: 'Test User'}
};
beforeEach(async(() => {
params = new Subject<Params>();
TestBed.configureTestingModule({
imports: [ ModalModule.forRoot(), SharedModule, HttpModule ],
declarations: [ OriginalComponent ],
providers: [ OriginalService, UserService, ComponentLoaderFactory,
{ provide: Router, useValue: userServiceStub }, {provide: ActivatedRoute, useValue: { params: params }} ]
})
.compileComponents();
})
);
beforeEach(() => {
fixture = TestBed.createComponent(ChecklistComponent);
component = fixture.componentInstance;
fixture.detectChanges();
it('should create', () => {
expect(component).toBeTruthy();
});
});
Please correct me how to properly use routing in test cases or stubs where I'm doing wrong.

"Can't resolve all parameters for MdDialogRef: (?)" Error when testing NG2 Material Dialog component

I have a login component as follows:
import { Component, OnInit } from '#angular/core';
import { MdDialogRef } from '#angular/material';
import { AuthService } from '../../core/services/auth.service';
#Component({
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss']
})
export class LoginDialogComponent implements OnInit {
model: {
email: string,
password: string
};
error;
constructor(
private authService: AuthService,
private dialogRef: MdDialogRef<LoginDialogComponent>
) { }
ngOnInit() {
this.model = {
email: '',
password: ''
};
}
signin() {
this.error = null;
this.authService.login(this.model.email, this.model.password).subscribe(data => {
this.dialogRef.close(data);
}, err => {
this.error = err.json();
});
}
}
And I have a test spec for this component as follows:
import { async, ComponentFixture, TestBed } from '#angular/core/testing';
import { MdDialogRef, OverlayRef } from '#angular/material';
import { AuthService } from '../../core/services/auth.service';
import { LoginDialogComponent } from './login.component';
describe('Component: Login', () => {
let component: LoginDialogComponent;
let fixture: ComponentFixture<LoginDialogComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
LoginDialogComponent
],
imports: [],
providers: [
AuthService,
MdDialogRef,
OverlayRef
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(LoginDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
I've tried a million different things, and no matter what I do, I get the following error:
Can't resolve all parameters for MdDialogRef: (?)
Here's the code for MdDialogRef, which only has 1 parameter, OverlayRef. What am I missing?
import { OverlayRef } from '../core';
import { Observable } from 'rxjs/Observable';
/**
* Reference to a dialog opened via the MdDialog service.
*/
export declare class MdDialogRef<T> {
private _overlayRef;
/** The instance of component opened into the dialog. */
componentInstance: T;
/** Subject for notifying the user that the dialog has finished closing. */
private _afterClosed;
constructor(_overlayRef: OverlayRef);
/**
* Close the dialog.
* #param dialogResult Optional result to return to the dialog opener.
*/
close(dialogResult?: any): void;
/** Gets an observable that is notified when the dialog is finished closing. */
afterClosed(): Observable<any>;
}
EDIT: taking a clue from #Ryan's comment, I tried removing the MdDialogRef provider entirely and got the following error:
Can't resolve all parameters for OverlayRef: (?, ?, ?)
This leads me to believe that the problem is actually w/MdDialogRef trying to resolve OverlayRef, not w/MdDialogRef itself.
WORKING EXAMPLE The code below is the actual working code, per Yurzui's suggestion.
/* tslint:disable:no-unused-variable */
import { NgModule } from '#angular/core';
import { async, TestBed } from '#angular/core/testing';
import { CommonModule } from '#angular/common';
import { FormsModule } from '#angular/forms';
import { MaterialModule, MdDialogModule, MdToolbarModule, MdDialog, MdDialogRef } from '#angular/material';
import { CoreModule } from '../../core/core.module';
import { LoginDialogComponent } from './login.component';
#NgModule({
declarations: [
LoginDialogComponent
],
entryComponents: [
LoginDialogComponent
],
exports: [
LoginDialogComponent
],
imports: [
CommonModule,
CoreModule,
FormsModule,
MaterialModule.forRoot(),
MdDialogModule.forRoot(),
MdToolbarModule.forRoot()
]
})
class LoginDialogSpecModule { }
describe('Component: Login Dialog', () => {
let component: LoginDialogComponent;
let dialog: MdDialog;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
LoginDialogSpecModule
]
});
});
beforeEach(() => {
dialog = TestBed.get(MdDialog);
let dialogRef = dialog.open(LoginDialogComponent);
component = dialogRef.componentInstance;
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
There is an issue ComponentFactoryResolver is not aware of components compiled via TestBed
According to this problem angular2 team offers workaround by creating real module with entryComponents property
https://github.com/angular/material2/blob/2.0.0-beta.1/src/lib/dialog/dialog.spec.ts#L387-L402
So your test could write like this:
import { MdDialog, MdDialogModule } from '#angular/material';
#NgModule({
declarations: [TestComponent],
entryComponents: [TestComponent],
exports: [TestComponent],
})
class TestModule { }
describe('Component: Login', () => {
let component: TestComponent;
let dialog: MdDialog;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [TestModule, MdDialogModule]
});
});
beforeEach(() => {
dialog = TestBed.get(MdDialog);
let dialogRef = dialog.open(TestComponent);
component = dialogRef.componentInstance;
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
Plunker Example
I was getting the same error when running my code normally, i.e. I did not write a test case.
I found that the line provides: [ MdDialogRef ]in my main component was giving this exact same error, and everything worked without it.

"Error: No provider for router" while writing Karma-Jasmine unit test cases

We have done one angular2 project set up and inside that created one module (my-module) and inside that module created one component (my-new-component) using following cmd commands:
ng new angular2test
cd angular2test
ng g module my-module
ng generate component my-new-component
After creating the set up and all components, we ran ng test command from cmd inside angular2test folder.
The below file is our my-new-component.component.ts file:
import { Component, OnInit } from '#angular/core';
import { Router, Routes, RouterModule } from '#angular/router';
import { DummyService } from '../services/dummy.service';
#Component({
selector: 'app-my-new-component',
templateUrl: './my-new-component.component.html',
styleUrls: ['./my-new-component.component.css']
})
export class MyNewComponentComponent implements OnInit {
constructor(private router : Router, private dummyService:DummyService) { }
ngOnInit() {
}
redirect() : void{
//this.router.navigate(['/my-module/my-new-component-1'])
}
}
The below file is our my-new-component.component.spec.ts file:
/* tslint:disable:no-unused-variable */
import { async, ComponentFixture, TestBed } from '#angular/core/testing';
import { By } from '#angular/platform-browser';
import { DebugElement } from '#angular/core';
import { RouterTestingModule } from '#angular/router/testing';
import {NgbModule} from '#ng-bootstrap/ng-bootstrap';
import { DummyService } from '../services/dummy.service';
import { MyNewComponentComponent } from './my-new-component.component';
describe('MyNewComponentComponent', () => {
let component: MyNewComponentComponent;
let fixture: ComponentFixture<MyNewComponentComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule, NgbModule.forRoot(), DummyService],
declarations: [ MyNewComponentComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MyNewComponentComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
We are getting the below cmd error while running the ng test command:
Chrome 54.0.2840 (Windows 7 0.0.0): Executed 1 of 1 (1 FAILED) ERROR (0.593 secs / 2.007 secs)
Chrome 54.0.2840 (Windows 7 0.0.0) MyNewComponentComponent should create FAILED
Failed: Unexpected value 'DummyService' imported by the module 'DynamicTestModule'
Error: Unexpected value 'DummyService' imported by the module 'DynamicTestModule'
We have updated the component file and the spec file. Pleased find below the code snippet.
The below file is our my-new-component.component.ts file:
import { Component, OnInit } from '#angular/core';
import { Router, Routes, RouterModule } from '#angular/router';
import { DummyService } from '../services/dummy.service';
#Component({
selector: 'app-my-new-component',
templateUrl: './my-new-component.component.html',
styleUrls: ['./my-new-component.component.css']
})
export class MyNewComponentComponent implements OnInit {
constructor(private router : Router, private dummyService:DummyService, public fb: FormBuilder) {
super(fb);
}
ngOnInit() {
}
redirect() : void{
//this.router.navigate(['/my-module/my-new-component-1'])
}
}
The below file is our my-new-component.component.spec.ts file:
/* tslint:disable:no-unused-variable */
import { async, ComponentFixture, TestBed } from '#angular/core/testing';
import { By } from '#angular/platform-browser';
import { DebugElement } from '#angular/core';
import { FormsModule, FormGroup, FormBuilder, Validators, ReactiveFormsModule} from '#angular/forms';
import { SplitPipe } from '../../common/pipes/string-split.pipe';
import { RouterTestingModule } from '#angular/router/testing';
import { DummyService } from '../services/dummy.service';
import { MyNewComponentComponent } from './my-new-component.component';
describe('MyNewComponentComponent', () => {
let component: MyNewComponentComponent;
let fixture: ComponentFixture<MyNewComponentComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule, DummyService ,HttpModule, FormBuilder],
declarations: [ MyNewComponentComponent, SplitPipe]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MyNewComponentComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
But while running the ng test command, we are getting the below error.
09 12 2016 09:13:48.987:WARN [karma]: No captured browser, open http://localhost:9876/
09 12 2016 09:13:49.008:INFO [karma]: Karma v1.2.0 server started at http://localhost:9876/
09 12 2016 09:13:49.010:INFO [launcher]: Launching browser Chrome with unlimited concurrency
09 12 2016 09:13:49.420:INFO [launcher]: Starting browser Chrome
09 12 2016 09:13:58.642:INFO [Chrome 54.0.2840 (Windows 7 0.0.0)]: Connected on socket /#QZ9LSSUVeK6KwNDlAAAA with id 46830907
Failed: Unexpected value 'FormBuilder' imported by the module 'DynamicTestModule'
Error: Unexpected value 'FormBuilder' imported by the module 'DynamicTestModule'
You need to import RouterTestingModule when setting up the test module.
/* tslint:disable:no-unused-variable */
import { async, ComponentFixture, TestBed } from '#angular/core/testing';
import { By } from '#angular/platform-browser';
import { DebugElement } from '#angular/core';
import { RouterTestingModule } from '#angular/router/testing';
import { MyNewComponentComponent } from './my-new-component.component';
describe('MyNewComponentComponent', () => {
let component: MyNewComponentComponent;
let fixture: ComponentFixture<MyNewComponentComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule],
declarations: [ MyNewComponentComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MyNewComponentComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
Edit: example with mock DummyService
/* tslint:disable:no-unused-variable */
import { async, ComponentFixture, TestBed } from '#angular/core/testing';
import { By } from '#angular/platform-browser';
import { DebugElement } from '#angular/core';
import { RouterTestingModule } from '#angular/router/testing';
import { MyNewComponentComponent } from './my-new-component.component';
// import the service
import { DummyService } from '../dummy.service';
// mock the service
class MockDummyService extends DummyService {
// mock everything used by the component
};
describe('MyNewComponentComponent', () => {
let component: MyNewComponentComponent;
let fixture: ComponentFixture<MyNewComponentComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule],
declarations: [MyNewComponentComponent],
providers: [{
provide: DummyService,
useClass: MockDummyService
}]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MyNewComponentComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
Add RouterTestingModule for configureTestingModule testCase
==> imports: [RouterTestingModule],
import {RouterTestingModule} from '#angular/router/testing';
beforeEach(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule], // <====
providers: [],
declarations: [],
});
});
I get the same kind of error and I want to share my solution to help others
The Error I get in Karma
error properties: Object({ ngTempTokenPath: null, ngTokenPath: [ 'RouterModule', 'Router', 'Function', 'Function' ] })
NullInjectorError: R3InjectorError(DynamicTestModule)[RouterModule -> Router -> Function -> Function]:
NullInjectorError: No provider for Function!
inventory-view.component.ts
#Component({
selector: 'app-inventory-view',
templateUrl: './inventory-view.component.html',
styleUrls: ['./inventory-view.component.scss'],
animations: []
})
export class InventoryViewComponent implements OnInit, AfterViewInit, OnDestroy {
constructor(
public router: Router, // <--- here was the problem
public activatedRoute: ActivatedRoute
) { }
In my test file
inventory-view.component.spec.ts
import { HttpClientModule } from '#angular/common/http';
import { waitForAsync, ComponentFixture, TestBed } from '#angular/core/testing';
import { RouterTestingModule } from '#angular/router/testing';
import { ActivatedRoute, convertToParamMap, Router } from '#angular/router';
const ActivatedRouteSpy = {
snapshot: {
paramMap: convertToParamMap({
some: 'some',
else: 'else',
})
},
queryParamMap: of(
convertToParamMap({
some: 'some',
else: 'else',
})
)
};
const RouterSpy = jasmine.createSpyObj(
'Router',
['navigate']
);
describe('InventoryViewComponent', () => {
let component: InventoryViewComponent;
let fixture: ComponentFixture<InventoryViewComponent>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
imports: [
HttpClientModule,
RouterTestingModule,
],
declarations: [ InventoryViewComponent ],
providers: [
{ provide: ActivatedRoute, useValue: ActivatedRouteSpy },
{ provide: Router, useValue: RouterSpy }
]
})
.compileComponents();
}));
beforeEach(waitForAsync(() => {
fixture = TestBed.createComponent(InventoryViewComponent);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});

angular 2 unit tests not able to find debugElement

I am trying to run unit tests on my component which is an output for my router. I have stubbed the router and service used by the component and I am trying to pull the element using the fixture.debugElement to confirm the tests are working. However this is always returning as NULL.
Tests
import { TestBed, async, ComponentFixture } from '#angular/core/testing';
import { Router } from '#angular/router';
import { By } from '#angular/platform-browser';
import { DebugElement } from '#angular/core';
import { HeroesComponent } from './heroes.component';
import { HeroService } from '../hero.service';
import { StubHeroService } from '../testing/stub-hero.service';
import { StubRouter } from '../testing/stub-router';
let comp: HeroesComponent;
let fixture: ComponentFixture<HeroesComponent>;
let de: DebugElement;
let el: HTMLElement;
describe('Component: Heroes', () => {
beforeEach( async(() => {
TestBed.configureTestingModule({
declarations: [HeroesComponent],
providers: [
{ provide: HeroService, useClass: StubHeroService },
{ provide: Router, useClass: StubRouter }
]
})
.compileComponents()
.then(() => {
fixture = TestBed.createComponent(HeroesComponent);
comp = fixture.componentInstance;
de = fixture.debugElement.query(By.css('*'));
console.log(de);
el = de.nativeElement;
});
}));
it('should create an instance', () => {
expect(comp).toBeTruthy();
});
it('should update the selected hero', () => {
comp.onSelect({
id: 0,
name: 'Zero'
});
fixture.detectChanges();
expect(el.querySelector('.selected').firstChild.textContent).toEqual(0);
});
});
Stubbed Router
export class StubRouter {
navigateByUrl(url: string) { return url; }
}
Before query the element call fixture.detectChanges
fixture = TestBed.createComponent(HeroesComponent);
comp = fixture.componentInstance;
//call detect changes here
fixture.detectChanges();
de = fixture.debugElement.query(By.css('*'));
console.log(de);
el = de.nativeElement;