Reputation: 1043
I am writing Unit Test cases for a function in Angular7 template . It is a login component and the login function has router.navigate inside the http request, to route to the dashboard on correct login. But I am getting error -
Error: Expected spy navigate to have been called with [ [ '/ProjectData/MasterSequence' ] ] but it was never called. at stack (http://localhost:9876/absolute/home/hp/Downloads/ICICI/ICICI_UI/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?0b1eaf7a13cae32191eadea482cfc96ae41fc22b:2455:17) at buildExpectationResult (http://localhost:9876/absolute/home/hp/Downloads/ICICI/ICICI_UI/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?0b1eaf7a13cae32191eadea482cfc96ae41fc22b:2425:14) at Spec.expectationResultFactory (http://localhost:9876/absolute/home/hp/Downloads/ICICI/ICICI_UI/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?0b1eaf7a13cae32191eadea482cfc96ae41fc22b:901:18) at Spec.addExpectationResult (http://localhost:9876/absolute/home/hp/Downloads/ICICI/ICICI_UI/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?0b1eaf7a13cae32191eadea482cfc96ae41fc22b:524:34) at Expectation.addExpectationResult (http://localhost:9876/absolute/home/hp/Downloads/ICICI/ICICI_UI/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?0b1eaf7a13cae32191eadea482cfc96ae41fc22b:845:21) at Expectation.toHaveBeenCalledWith (http://localhost:9876/absolute/home/hp/Downloads/ICICI/ICICI_UI/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?0b1eaf7a13cae32191eadea482cfc96ae41fc22b:2369:12) at UserContext. (http://localhost:9876/src/app/authentication/login2/login2.component.spec.ts?:208:38)
app.component.html
loginData(value) {
this.username = value.username;
this.password = value.password;
this.dataObj = {
'username': this.username,
'password': this.password
}
this.loginService.login(this.dataObj).then((data) => {
console.log("data", data);
this.response = data;
console.log("message", this.response.message);
if (this.response.message == "Login Successful.") {
this.router.navigate(['/ProjectData/MasterSequence'])
}
else {
this.toastr.error("UserName or Password is incorrect");
}
})
app.component.spec.ts
describe('Login2Component', () => {
let comp: Login2Component;
let fixture: ComponentFixture<Login2Component>;
let de: DebugElement;
let el: HTMLElement;
beforeEach(async(() => {
mockRouter = { navigate: jasmine.createSpy('navigate') };
TestBed.configureTestingModule({
declarations: [Login2Component, MasterSequenceComponent],
imports: [
BrowserModule,
FormsModule,
RouterModule,
ReactiveFormsModule,
RouterTestingModule,
HttpClientModule,
[
RouterTestingModule.withRoutes([
{ path: '/ProjectData/MasterSequence',
component: MasterSequenceComponent }
])
]
],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
providers: [{ provide: ToastrService, useValue: ToastrService }, Login2Service]
})
.compileComponents()
.then(() => {
//Login2Component
fixture = TestBed.createComponent(Login2Component);
comp = fixture.componentInstance;
de = fixture.debugElement.query(By.css('form'));
el = de.nativeElement;
});
}));
it('should redirect the user to "login form" component when button is clicked', () => {
const router = TestBed.get(Router);
const spy = spyOn(router, 'navigate');
fixture.detectChanges();
const button = fixture.debugElement.query(By.css('form[id=loginform]'));
button.triggerEventHandler('click', null);
let userN = comp.addLoginData.controls['username'];
userN.setValue('pallavi');
let pass = comp.addLoginData.controls['password'];
pass.setValue(1234);
let value = {
username: userN,
password: pass
};
comp.loginData(value);
expect(spy).toHaveBeenCalledWith(['/ProjectData/MasterSequence']);
});
});
Reference -
Angular 2/4/6/7 - Unit Testing with Router
Further Error On using this code -
it('should redirect the user to "login form" component when button is clicked', () => {
let value = {
username: 'user123',
password: 'pwd'
};
comp.username = '';
comp.password = '';
spyOn(comp.LoginService,'login').and.callThrough();
comp.loginData(value);
expect(comp.username).toBe('user123');
expect(comp.password).toBe('pwd');
expect(comp.LoginService.login).toHaveBeenCalledWith(value)
//expect(RouterMock.navigate).toHaveBeenCalledWith(['/ProjectData/MasterSe//quence']);
});
ERROR: 'Unhandled Promise rejection:', HttpErrorResponse{headers: HttpHeaders{normalizedNames: Map{}, lazyUpdate: null, he aders: Map{}}, status: 0, statusText: 'Unknown Error', url: 'http://192.168.5.128:3002/api/user/login', ok: false, name: 'HttpErrorResponse', message: 'Http failure response for http://192.168.5.128:3002/api/user/login: 0 Unknown Error', error: ProgressEvent{isTrusted: true}}, '; Zone:', 'ProxyZone', '; Task:', 'Promise.then', '; Value:', HttpErrorResponse{headers: HttpHeaders{normalizedNames: Map{}, lazyUpdate: null, headers: Map{}}, status: 0, statusText: 'Unknown Error', url: 'http://192.168.5.128:3002/api/user/login', ok: false, name: 'HttpErrorResponse', message: 'Http failure response for http://192.168.5.128:3002/api/user/login: 0 Unknown Error', error: ProgressEvent{isTrusted: true}}, undefined
Upvotes: 1
Views: 6806
Reputation: 17494
I cant find code of loginService.login()
but I am sure that it must be making some API call, so its a good practice to create a stub
. something like:
export class LoginServiceStub{
login(obj){
return new Promise((resolve, reject) => {
resolve("whatever_data_is_expected");
});
}
}
In spec
file:
describe('Login2Component', () => {
let RouterMock = {
navigate: jasmine.createSpy('navigate')
};
beforeEach(async(() => {
mockRouter = { navigate: jasmine.createSpy('navigate') };
TestBed.configureTestingModule({
decleration: [ .... ],
providers: [
{provide: ToastrService, useValue: ToastrService }, // I am not sure why you have done "useValue" with same Service
{provide: Login2Service, useClass: Login2ServiceStub },
{provide: Router, useValue: RouterMock }
],
// ... and other deceleration of Test Bed
)};
})
and then in it
block:
it('should redirect the user to "login form" component when button is clicked', () => {
let value = {
username: 'user123',
password: 'pwd';
};
comp.username = '';
comp.password = '';
spyOn(comp.loginService,'login').and.callThrough();
comp.loginData(value);
expect(comp.username).toBe('user123');
expect(comp.password).toBe('pwd');
expect(comp.loginService.login).toHaveBeenCalledWith(value)
expect(RouterMock.navigate).toHaveBeenCalledWith(['/ProjectData/MasterSequence']);
});
});
I would also suggest you to read this collection of articles specifically written for Unit testing in Angular. You can find several links which will cover almost all basic testing scenarios.
Upvotes: 1