Angular 预期已使用[[';/ProjectData/MasterSequence&\x27;]调用间谍导航,但从未调用它
我正在Angular7模板中为函数编写单元测试用例。它是一个登录组件,登录函数具有router.navigate(路由器)。在http请求中导航,以便在正确登录时路由到仪表板。 但我得到了一个错误- 错误:应使用[['/ProjectData/MasterSequence']]调用spy navigate,但从未调用它。 在堆栈()处 在buildExpectationResult()处 按规格expectationResultFactory() 按规格添加预期结果() at Expectation.addExpectationResult() 在期望中。已被()调用 在UserContext。() app.component.htmlAngular 预期已使用[[';/ProjectData/MasterSequence&\x27;]调用间谍导航,但从未调用它,angular,typescript,unit-testing,jasmine,karma-jasmine,Angular,Typescript,Unit Testing,Jasmine,Karma Jasmine,我正在Angular7模板中为函数编写单元测试用例。它是一个登录组件,登录函数具有router.navigate(路由器)。在http请求中导航,以便在正确登录时路由到仪表板。 但我得到了一个错误- 错误:应使用[['/ProjectData/MasterSequence']]调用spy navigate,但从未调用它。 在堆栈()处 在buildExpectationResult()处 按规格expectationResultFactory() 按规格添加预期结果() at Expectati
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");
}
})
应用组件规范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']);
});
});
错误:“未处理的承诺拒绝:”,HttpErrorResponse{headers:HttpHeaders{normalizedNames:Map{},lazyUpdate:null,他
aders:Map{},状态:0,状态文本:“未知错误”,url:“”,ok:false,名称:“HttpErrorResponse”,消息:“0未知错误的Http失败响应”,错误:ProgressEvent{isTrusted:true},”;区域:','ProxyZone',';任务:','承诺.然后',';值:',HttpErrorResponse{headers:HttpHeaders{normalizedNames:Map{},lazyUpdate:null,headers:Map{},状态:0,状态文本:“未知错误”,url:,ok:false,名称:“HttpErrorResponse”,消息:“Http失败响应:0未知错误”,错误:ProgressEvent{isTrusted:true},未定义
我找不到
loginService.login()
的代码,但我确信它一定在进行一些API调用,因此创建存根是一个很好的做法。比如:
export class LoginServiceStub{
login(obj){
return new Promise((resolve, reject) => {
resolve("whatever_data_is_expected");
});
}
}
在spec
文件中:
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
)};
})
然后在it
块中:
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']);
});
});
我也建议你去。您可以找到几个链接,这些链接将涵盖几乎所有的基本测试场景 请您提供与该测试相关的组件和模板,否则要想弄清楚为什么您的测试不能按预期工作有点困难。好的。谢谢如果没有看到html,我会做得很好。我真的不明白为什么你会触发一个按钮点击。您可能需要等待异步作业完成,但这只是猜测。但有一个问题是,您肯定需要等到loginService返回的承诺真正解决。您可以在测试块it
中使用fakeAsync
和tick()。但是,单凭这一点是否就能解决您的测试问题,我无法判断是否还没有看到模板。此外,您使用real Login2Service的原因是什么?@Techdive聊天中提供的我的建议有任何更新吗?嗨,Shashank,谢谢您的回复。但我收到错误消息-类型“LoginComponent”上不存在属性“LoginService”。我猜…它不承认登录服务或loginService@Techdive:你能在构造函数constructor(public login service)
etc等中检查它是否是公共的吗?在更正之后,我仍然得到错误-预期spy navigate已被[['/ProjectData/MasterSequence']]调用,但它从未被调用。@Shashank,如果我删除最后一行-i get error-error:'未处理的承诺拒绝:',HttpErrorResponse{headers:HttpHeaders{normalizedNames:Map{},lazyUpdate:null,headers:Map{},状态:0,状态文本:“未知错误”,url:“”,确定:false,名称:“HttpErrorResponse”,消息:“0未知错误的Http失败响应”,……错误:ProgressEvent{isTrusted:true},”;区域:','ProxyZone',';任务:','承诺.然后',';值:',HttpErrorResponse{headers:HttpHeaders{normalizedNames:Map{},lazyUpdate:null,headers:Map{},状态:0,状态文本:“未知错误”,url:,ok:false,名称:“HttpErrorResponse”,消息:“Http失败响应:0未知错误”,错误:ProgressEvent{isTrusted:true},未定义
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']);
});
});