如何对 angular 中的 BehaviorSubject 订阅进行单元测试
how to unit test subscription to a BehaviourSubject in angular
我有一个 UserManagementService
,它公开了一个 BehaviourSubject
的 Observable
。
this.userSignInState$ = this.signInStateSubject.asObservable();
我在 nav
组件中订阅了 userSignInState
。
constructor(public userManagementService: UserManagementService, private fb:FormBuilder, private helper:HelperService) {
this.userSignInStateSubscription = this.userManagementService.userSignInState$.subscribe(
(result:Result)=> {
console.log("In nav - result from user signin state ",result);
let subscribed:UserSigninState = result.additionalInfo;
console.log("new user signin state received:", subscribed);
this.userLoggedIn = subscribed.isSignedIn;
if(subscribed.isSignedIn && subscribed['additional-info'] !== ''){
this.profile = JSON.parse(subscribed['additional-info']) as UserProfileAPI
}
if(!subscribed.isSignedIn && subscribed['additional-info'] !== ''){
// let error:ServerResponseAPI = JSON.parse(subscribed['additional-info']) as ServerResponseAPI
//let errorMessage:string = this.helper.userFriendlyErrorMessage(error);
this.navEvent.emit(new NavContext(subscribed['additional-info']));
}
},
(error:ServerResponseAPI)=>{
console.log("got error from the Observable: ",error);
let errorMessage:string = this.helper.userFriendlyErrorMessage(error);
this.navEvent.emit(new NavContext(errorMessage));
// this.userloggedIn =false;
},
()=>{ //observable complete
console.log("observable completed")
//this.userloggedIn =false;
});
}
我想进行单元测试nav
。 spec
应该测试 component
订阅 userSignInState$
并正确处理 Result
。我该怎么做呢?由于这是一个单元测试,我不想使用真正的 UserManagementService
我写了以下规范
fit('should subscribe to user sign in state observable',()=>{
let userManagementService = TestBed.get(UserManagementService);
let navComponent:NavComponentComponent = component;
console.log('component is ',navComponent);
navComponent.userLoggedIn = false;
let dummyUserProfile = new UserProfileAPI(new User('fn','ln','test@test.com'));
userManagementService.signInStateSubject.next(new Result('success',(new UserSigninState(true,JSON.stringify(dummyUserProfile ))).toString));
expect(navComponent.userLoggedIn).toBe(true)
});
但我收到错误 Expected undefined to be true.
我不明白为什么 userLoggedIn
是未定义的。我已经在 nav
class
中声明了它
export class NavComponentComponent implements OnInit {
userLoggedIn:boolean;
...
}
我设置在ngOnInit
.
ngOnInit(){
this.userLoggedIn = false;
...
}
我也将订阅逻辑移至 ngOnInit
,但这也不起作用,结果相同。
问题出在我创建 Result
的方式上。我不应该将 .toString
与 userSignInState
一起使用。来自我在 SO
、"reference to .toString without () is just a reference to that function, so if you log that you get the code for that function." 和 "toString() will not work as userSignInState doesn't have a meanigful string representation and is defaulting to [object Object]" 中发布的另一个问题。我删除了 toString
并且代码作为 additional-info
是类型 any
我有一个 UserManagementService
,它公开了一个 BehaviourSubject
的 Observable
。
this.userSignInState$ = this.signInStateSubject.asObservable();
我在 nav
组件中订阅了 userSignInState
。
constructor(public userManagementService: UserManagementService, private fb:FormBuilder, private helper:HelperService) {
this.userSignInStateSubscription = this.userManagementService.userSignInState$.subscribe(
(result:Result)=> {
console.log("In nav - result from user signin state ",result);
let subscribed:UserSigninState = result.additionalInfo;
console.log("new user signin state received:", subscribed);
this.userLoggedIn = subscribed.isSignedIn;
if(subscribed.isSignedIn && subscribed['additional-info'] !== ''){
this.profile = JSON.parse(subscribed['additional-info']) as UserProfileAPI
}
if(!subscribed.isSignedIn && subscribed['additional-info'] !== ''){
// let error:ServerResponseAPI = JSON.parse(subscribed['additional-info']) as ServerResponseAPI
//let errorMessage:string = this.helper.userFriendlyErrorMessage(error);
this.navEvent.emit(new NavContext(subscribed['additional-info']));
}
},
(error:ServerResponseAPI)=>{
console.log("got error from the Observable: ",error);
let errorMessage:string = this.helper.userFriendlyErrorMessage(error);
this.navEvent.emit(new NavContext(errorMessage));
// this.userloggedIn =false;
},
()=>{ //observable complete
console.log("observable completed")
//this.userloggedIn =false;
});
}
我想进行单元测试nav
。 spec
应该测试 component
订阅 userSignInState$
并正确处理 Result
。我该怎么做呢?由于这是一个单元测试,我不想使用真正的 UserManagementService
我写了以下规范
fit('should subscribe to user sign in state observable',()=>{
let userManagementService = TestBed.get(UserManagementService);
let navComponent:NavComponentComponent = component;
console.log('component is ',navComponent);
navComponent.userLoggedIn = false;
let dummyUserProfile = new UserProfileAPI(new User('fn','ln','test@test.com'));
userManagementService.signInStateSubject.next(new Result('success',(new UserSigninState(true,JSON.stringify(dummyUserProfile ))).toString));
expect(navComponent.userLoggedIn).toBe(true)
});
但我收到错误 Expected undefined to be true.
我不明白为什么 userLoggedIn
是未定义的。我已经在 nav
class
export class NavComponentComponent implements OnInit {
userLoggedIn:boolean;
...
}
我设置在ngOnInit
.
ngOnInit(){
this.userLoggedIn = false;
...
}
我也将订阅逻辑移至 ngOnInit
,但这也不起作用,结果相同。
问题出在我创建 Result
的方式上。我不应该将 .toString
与 userSignInState
一起使用。来自我在 SO
、"reference to .toString without () is just a reference to that function, so if you log that you get the code for that function." 和 "toString() will not work as userSignInState doesn't have a meanigful string representation and is defaulting to [object Object]" 中发布的另一个问题。我删除了 toString
并且代码作为 additional-info
是类型 any