how to send message from an Observable to an Observer in Unit test












0















I have a UserManagementService which exposes an Observable of a BehaviourSubject.



this.userSignInState$ = this.signInStateSubject.asObservable();



userSignInState$ is public while signInStateSubject is private.



I subscribe to the userSignInState$ in a nav component.



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;
});
}


I want to unit test nav. As part of the spec, I want to use next of the signInStateSubject and check that nav gets the message sent in next. But I can't do this as signInStateSubject is private. I could do this if I make signInStateSubject public but that doesn't sound right. The



I wrote the following spec but it works only if I make signInStateSubject public.



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 ))))); //THIS WORKS ONLY IF signInStateSubject IS PUBLIC
expect(navComponent.userLoggedIn).toBe(true)
});









share|improve this question



























    0















    I have a UserManagementService which exposes an Observable of a BehaviourSubject.



    this.userSignInState$ = this.signInStateSubject.asObservable();



    userSignInState$ is public while signInStateSubject is private.



    I subscribe to the userSignInState$ in a nav component.



    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;
    });
    }


    I want to unit test nav. As part of the spec, I want to use next of the signInStateSubject and check that nav gets the message sent in next. But I can't do this as signInStateSubject is private. I could do this if I make signInStateSubject public but that doesn't sound right. The



    I wrote the following spec but it works only if I make signInStateSubject public.



    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 ))))); //THIS WORKS ONLY IF signInStateSubject IS PUBLIC
    expect(navComponent.userLoggedIn).toBe(true)
    });









    share|improve this question

























      0












      0








      0








      I have a UserManagementService which exposes an Observable of a BehaviourSubject.



      this.userSignInState$ = this.signInStateSubject.asObservable();



      userSignInState$ is public while signInStateSubject is private.



      I subscribe to the userSignInState$ in a nav component.



      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;
      });
      }


      I want to unit test nav. As part of the spec, I want to use next of the signInStateSubject and check that nav gets the message sent in next. But I can't do this as signInStateSubject is private. I could do this if I make signInStateSubject public but that doesn't sound right. The



      I wrote the following spec but it works only if I make signInStateSubject public.



      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 ))))); //THIS WORKS ONLY IF signInStateSubject IS PUBLIC
      expect(navComponent.userLoggedIn).toBe(true)
      });









      share|improve this question














      I have a UserManagementService which exposes an Observable of a BehaviourSubject.



      this.userSignInState$ = this.signInStateSubject.asObservable();



      userSignInState$ is public while signInStateSubject is private.



      I subscribe to the userSignInState$ in a nav component.



      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;
      });
      }


      I want to unit test nav. As part of the spec, I want to use next of the signInStateSubject and check that nav gets the message sent in next. But I can't do this as signInStateSubject is private. I could do this if I make signInStateSubject public but that doesn't sound right. The



      I wrote the following spec but it works only if I make signInStateSubject public.



      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 ))))); //THIS WORKS ONLY IF signInStateSubject IS PUBLIC
      expect(navComponent.userLoggedIn).toBe(true)
      });






      jasmine rxjs angular6 angular-testing






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Jan 1 at 11:39









      Manu ChadhaManu Chadha

      3,25821541




      3,25821541
























          1 Answer
          1






          active

          oldest

          votes


















          0














          As I am doing unit testing, I should have mocked the UserManagementService. To do this. I created a mock class which contains the methods and properties of UserManagementService which nav uses.



          class MockUserManagementService {
          signInStateSubject:BehaviorSubject<Result> ;
          userSignInState$:Observable<Result>;//naming convention for Streams has $ in the end.

          constructor(){
          this.signInStateSubject = new BehaviorSubject<Result>(new Result('initial',""));//create Observable. Other components can subscribe to it now to get notifications/values
          this.userSignInState$ = this.signInStateSubject.asObservable();

          }
          getUserProfile(userId: UserID){
          console.log('mocked getUserProfile called');
          }
          }


          then I provide the mocked class in place of the real UserManagementClass



          beforeEach(async(() => {
          TestBed.configureTestingModule({
          declarations: [ ...],
          imports:[...],
          providers:[...,
          {provide: UserManagementService,useClass:MockUserManagementService},//mock user management service
          })
          .compileComponents();
          }));


          The specs are as they were earlier. But this time, I didn't need to make any properties of the real UserManagementService public as the service is mocked!



          it('should subscribe to user sign in state observable',()=>{
          let navComponent:NavComponentComponent = component;
          let userManagementService = TestBed.get(UserManagementService);//component.userManagementService;
          console.log('mock service is ',userManagementService);
          console.log('subject is ',userManagementService.signInStateSubject);
          console.log('observable is ',userManagementService.userSignInState$);
          console.log('nav is ',navComponent);
          expect(navComponent.userSignInStateSubscription.closed).toBe(false);
          });

          it('should should set user as signedIn for successful signin attempt',()=>{
          let navComponent:NavComponentComponent = component;
          /*The idea of unit test is that UserManagementService might not be available yet
          so mock UserManagementService
          */
          let userManagementService = TestBed.get(UserManagementService);//component.userManagementService;
          console.log('got mocked user management service',userManagementService);
          //component.subscribeToUserSignInState();
          console.log('component is ',navComponent);
          navComponent.userLoggedIn = false;
          let dummyUserProfile = new UserProfileAPI(new User('manu','chadha','test@test.com'));
          console.log('dummy profile is ',dummyUserProfile);
          console.log('dummy profile is JSON stringify',JSON.stringify(dummyUserProfile));
          let userSignInState = new UserSigninState(true,JSON.stringify(dummyUserProfile));
          console.log('user signin state ',userSignInState);
          userManagementService.signInStateSubject.next(new Result('success',userSignInState));
          //userManagementService.signInStateSubject.next(new Result('success1',(new UserSigninState(true,JSON.stringify(dummyUserProfile))).toString));
          expect(navComponent.userLoggedIn).toBe(true)
          });

          it('should get user's profile',()=>{
          let userManagementService = TestBed.get(UserManagementService);
          let navComponent:NavComponentComponent = component;
          console.log('component is ',navComponent);
          navComponent.profile = new UserProfileAPI(new User("fn","ln","test@test.com"));
          spyOn(userManagementService,'getUserProfile');
          component.onProfileClick();
          let userId = new UserID(navComponent.profile['external-profile'].email);
          expect(userManagementService.getUserProfile).toHaveBeenCalledWith(userId);
          });





          share|improve this answer























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53995123%2fhow-to-send-message-from-an-observable-to-an-observer-in-unit-test%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            0














            As I am doing unit testing, I should have mocked the UserManagementService. To do this. I created a mock class which contains the methods and properties of UserManagementService which nav uses.



            class MockUserManagementService {
            signInStateSubject:BehaviorSubject<Result> ;
            userSignInState$:Observable<Result>;//naming convention for Streams has $ in the end.

            constructor(){
            this.signInStateSubject = new BehaviorSubject<Result>(new Result('initial',""));//create Observable. Other components can subscribe to it now to get notifications/values
            this.userSignInState$ = this.signInStateSubject.asObservable();

            }
            getUserProfile(userId: UserID){
            console.log('mocked getUserProfile called');
            }
            }


            then I provide the mocked class in place of the real UserManagementClass



            beforeEach(async(() => {
            TestBed.configureTestingModule({
            declarations: [ ...],
            imports:[...],
            providers:[...,
            {provide: UserManagementService,useClass:MockUserManagementService},//mock user management service
            })
            .compileComponents();
            }));


            The specs are as they were earlier. But this time, I didn't need to make any properties of the real UserManagementService public as the service is mocked!



            it('should subscribe to user sign in state observable',()=>{
            let navComponent:NavComponentComponent = component;
            let userManagementService = TestBed.get(UserManagementService);//component.userManagementService;
            console.log('mock service is ',userManagementService);
            console.log('subject is ',userManagementService.signInStateSubject);
            console.log('observable is ',userManagementService.userSignInState$);
            console.log('nav is ',navComponent);
            expect(navComponent.userSignInStateSubscription.closed).toBe(false);
            });

            it('should should set user as signedIn for successful signin attempt',()=>{
            let navComponent:NavComponentComponent = component;
            /*The idea of unit test is that UserManagementService might not be available yet
            so mock UserManagementService
            */
            let userManagementService = TestBed.get(UserManagementService);//component.userManagementService;
            console.log('got mocked user management service',userManagementService);
            //component.subscribeToUserSignInState();
            console.log('component is ',navComponent);
            navComponent.userLoggedIn = false;
            let dummyUserProfile = new UserProfileAPI(new User('manu','chadha','test@test.com'));
            console.log('dummy profile is ',dummyUserProfile);
            console.log('dummy profile is JSON stringify',JSON.stringify(dummyUserProfile));
            let userSignInState = new UserSigninState(true,JSON.stringify(dummyUserProfile));
            console.log('user signin state ',userSignInState);
            userManagementService.signInStateSubject.next(new Result('success',userSignInState));
            //userManagementService.signInStateSubject.next(new Result('success1',(new UserSigninState(true,JSON.stringify(dummyUserProfile))).toString));
            expect(navComponent.userLoggedIn).toBe(true)
            });

            it('should get user's profile',()=>{
            let userManagementService = TestBed.get(UserManagementService);
            let navComponent:NavComponentComponent = component;
            console.log('component is ',navComponent);
            navComponent.profile = new UserProfileAPI(new User("fn","ln","test@test.com"));
            spyOn(userManagementService,'getUserProfile');
            component.onProfileClick();
            let userId = new UserID(navComponent.profile['external-profile'].email);
            expect(userManagementService.getUserProfile).toHaveBeenCalledWith(userId);
            });





            share|improve this answer




























              0














              As I am doing unit testing, I should have mocked the UserManagementService. To do this. I created a mock class which contains the methods and properties of UserManagementService which nav uses.



              class MockUserManagementService {
              signInStateSubject:BehaviorSubject<Result> ;
              userSignInState$:Observable<Result>;//naming convention for Streams has $ in the end.

              constructor(){
              this.signInStateSubject = new BehaviorSubject<Result>(new Result('initial',""));//create Observable. Other components can subscribe to it now to get notifications/values
              this.userSignInState$ = this.signInStateSubject.asObservable();

              }
              getUserProfile(userId: UserID){
              console.log('mocked getUserProfile called');
              }
              }


              then I provide the mocked class in place of the real UserManagementClass



              beforeEach(async(() => {
              TestBed.configureTestingModule({
              declarations: [ ...],
              imports:[...],
              providers:[...,
              {provide: UserManagementService,useClass:MockUserManagementService},//mock user management service
              })
              .compileComponents();
              }));


              The specs are as they were earlier. But this time, I didn't need to make any properties of the real UserManagementService public as the service is mocked!



              it('should subscribe to user sign in state observable',()=>{
              let navComponent:NavComponentComponent = component;
              let userManagementService = TestBed.get(UserManagementService);//component.userManagementService;
              console.log('mock service is ',userManagementService);
              console.log('subject is ',userManagementService.signInStateSubject);
              console.log('observable is ',userManagementService.userSignInState$);
              console.log('nav is ',navComponent);
              expect(navComponent.userSignInStateSubscription.closed).toBe(false);
              });

              it('should should set user as signedIn for successful signin attempt',()=>{
              let navComponent:NavComponentComponent = component;
              /*The idea of unit test is that UserManagementService might not be available yet
              so mock UserManagementService
              */
              let userManagementService = TestBed.get(UserManagementService);//component.userManagementService;
              console.log('got mocked user management service',userManagementService);
              //component.subscribeToUserSignInState();
              console.log('component is ',navComponent);
              navComponent.userLoggedIn = false;
              let dummyUserProfile = new UserProfileAPI(new User('manu','chadha','test@test.com'));
              console.log('dummy profile is ',dummyUserProfile);
              console.log('dummy profile is JSON stringify',JSON.stringify(dummyUserProfile));
              let userSignInState = new UserSigninState(true,JSON.stringify(dummyUserProfile));
              console.log('user signin state ',userSignInState);
              userManagementService.signInStateSubject.next(new Result('success',userSignInState));
              //userManagementService.signInStateSubject.next(new Result('success1',(new UserSigninState(true,JSON.stringify(dummyUserProfile))).toString));
              expect(navComponent.userLoggedIn).toBe(true)
              });

              it('should get user's profile',()=>{
              let userManagementService = TestBed.get(UserManagementService);
              let navComponent:NavComponentComponent = component;
              console.log('component is ',navComponent);
              navComponent.profile = new UserProfileAPI(new User("fn","ln","test@test.com"));
              spyOn(userManagementService,'getUserProfile');
              component.onProfileClick();
              let userId = new UserID(navComponent.profile['external-profile'].email);
              expect(userManagementService.getUserProfile).toHaveBeenCalledWith(userId);
              });





              share|improve this answer


























                0












                0








                0







                As I am doing unit testing, I should have mocked the UserManagementService. To do this. I created a mock class which contains the methods and properties of UserManagementService which nav uses.



                class MockUserManagementService {
                signInStateSubject:BehaviorSubject<Result> ;
                userSignInState$:Observable<Result>;//naming convention for Streams has $ in the end.

                constructor(){
                this.signInStateSubject = new BehaviorSubject<Result>(new Result('initial',""));//create Observable. Other components can subscribe to it now to get notifications/values
                this.userSignInState$ = this.signInStateSubject.asObservable();

                }
                getUserProfile(userId: UserID){
                console.log('mocked getUserProfile called');
                }
                }


                then I provide the mocked class in place of the real UserManagementClass



                beforeEach(async(() => {
                TestBed.configureTestingModule({
                declarations: [ ...],
                imports:[...],
                providers:[...,
                {provide: UserManagementService,useClass:MockUserManagementService},//mock user management service
                })
                .compileComponents();
                }));


                The specs are as they were earlier. But this time, I didn't need to make any properties of the real UserManagementService public as the service is mocked!



                it('should subscribe to user sign in state observable',()=>{
                let navComponent:NavComponentComponent = component;
                let userManagementService = TestBed.get(UserManagementService);//component.userManagementService;
                console.log('mock service is ',userManagementService);
                console.log('subject is ',userManagementService.signInStateSubject);
                console.log('observable is ',userManagementService.userSignInState$);
                console.log('nav is ',navComponent);
                expect(navComponent.userSignInStateSubscription.closed).toBe(false);
                });

                it('should should set user as signedIn for successful signin attempt',()=>{
                let navComponent:NavComponentComponent = component;
                /*The idea of unit test is that UserManagementService might not be available yet
                so mock UserManagementService
                */
                let userManagementService = TestBed.get(UserManagementService);//component.userManagementService;
                console.log('got mocked user management service',userManagementService);
                //component.subscribeToUserSignInState();
                console.log('component is ',navComponent);
                navComponent.userLoggedIn = false;
                let dummyUserProfile = new UserProfileAPI(new User('manu','chadha','test@test.com'));
                console.log('dummy profile is ',dummyUserProfile);
                console.log('dummy profile is JSON stringify',JSON.stringify(dummyUserProfile));
                let userSignInState = new UserSigninState(true,JSON.stringify(dummyUserProfile));
                console.log('user signin state ',userSignInState);
                userManagementService.signInStateSubject.next(new Result('success',userSignInState));
                //userManagementService.signInStateSubject.next(new Result('success1',(new UserSigninState(true,JSON.stringify(dummyUserProfile))).toString));
                expect(navComponent.userLoggedIn).toBe(true)
                });

                it('should get user's profile',()=>{
                let userManagementService = TestBed.get(UserManagementService);
                let navComponent:NavComponentComponent = component;
                console.log('component is ',navComponent);
                navComponent.profile = new UserProfileAPI(new User("fn","ln","test@test.com"));
                spyOn(userManagementService,'getUserProfile');
                component.onProfileClick();
                let userId = new UserID(navComponent.profile['external-profile'].email);
                expect(userManagementService.getUserProfile).toHaveBeenCalledWith(userId);
                });





                share|improve this answer













                As I am doing unit testing, I should have mocked the UserManagementService. To do this. I created a mock class which contains the methods and properties of UserManagementService which nav uses.



                class MockUserManagementService {
                signInStateSubject:BehaviorSubject<Result> ;
                userSignInState$:Observable<Result>;//naming convention for Streams has $ in the end.

                constructor(){
                this.signInStateSubject = new BehaviorSubject<Result>(new Result('initial',""));//create Observable. Other components can subscribe to it now to get notifications/values
                this.userSignInState$ = this.signInStateSubject.asObservable();

                }
                getUserProfile(userId: UserID){
                console.log('mocked getUserProfile called');
                }
                }


                then I provide the mocked class in place of the real UserManagementClass



                beforeEach(async(() => {
                TestBed.configureTestingModule({
                declarations: [ ...],
                imports:[...],
                providers:[...,
                {provide: UserManagementService,useClass:MockUserManagementService},//mock user management service
                })
                .compileComponents();
                }));


                The specs are as they were earlier. But this time, I didn't need to make any properties of the real UserManagementService public as the service is mocked!



                it('should subscribe to user sign in state observable',()=>{
                let navComponent:NavComponentComponent = component;
                let userManagementService = TestBed.get(UserManagementService);//component.userManagementService;
                console.log('mock service is ',userManagementService);
                console.log('subject is ',userManagementService.signInStateSubject);
                console.log('observable is ',userManagementService.userSignInState$);
                console.log('nav is ',navComponent);
                expect(navComponent.userSignInStateSubscription.closed).toBe(false);
                });

                it('should should set user as signedIn for successful signin attempt',()=>{
                let navComponent:NavComponentComponent = component;
                /*The idea of unit test is that UserManagementService might not be available yet
                so mock UserManagementService
                */
                let userManagementService = TestBed.get(UserManagementService);//component.userManagementService;
                console.log('got mocked user management service',userManagementService);
                //component.subscribeToUserSignInState();
                console.log('component is ',navComponent);
                navComponent.userLoggedIn = false;
                let dummyUserProfile = new UserProfileAPI(new User('manu','chadha','test@test.com'));
                console.log('dummy profile is ',dummyUserProfile);
                console.log('dummy profile is JSON stringify',JSON.stringify(dummyUserProfile));
                let userSignInState = new UserSigninState(true,JSON.stringify(dummyUserProfile));
                console.log('user signin state ',userSignInState);
                userManagementService.signInStateSubject.next(new Result('success',userSignInState));
                //userManagementService.signInStateSubject.next(new Result('success1',(new UserSigninState(true,JSON.stringify(dummyUserProfile))).toString));
                expect(navComponent.userLoggedIn).toBe(true)
                });

                it('should get user's profile',()=>{
                let userManagementService = TestBed.get(UserManagementService);
                let navComponent:NavComponentComponent = component;
                console.log('component is ',navComponent);
                navComponent.profile = new UserProfileAPI(new User("fn","ln","test@test.com"));
                spyOn(userManagementService,'getUserProfile');
                component.onProfileClick();
                let userId = new UserID(navComponent.profile['external-profile'].email);
                expect(userManagementService.getUserProfile).toHaveBeenCalledWith(userId);
                });






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Jan 2 at 20:40









                Manu ChadhaManu Chadha

                3,25821541




                3,25821541
































                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53995123%2fhow-to-send-message-from-an-observable-to-an-observer-in-unit-test%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    android studio warns about leanback feature tag usage required on manifest while using Unity exported app?

                    SQL update select statement

                    'app-layout' is not a known element: how to share Component with different Modules