Why Jasmine spy function in Angular is not being triggered by callback?












1















I want to test this.communication.subscribe() call which is having a callback in argument:



constructor (private communication: CommunicationProvider)

ngOnInit() {
this.communication.subscribe(() => {
this.router.navigate(["/success"]);
});
}


I have used callFake to mock the implementation to call callback()



beforeEach(async(() => {
communicationSpy = jasmine.createSpyObj("CommunicationProvider", ["subscribe"]);
routerSpy = jasmine.createSpyObj<Router>("Router", ["navigate"]);

communicationSpy.subscribe.and.callFake((callback: any) => {
callback();
});
}));

it("should route on callback", (done: DoneFn) => {
setTimeout(() => {
expect(routerSpy.navigate).toHaveBeenCalledWith(["/success"]);
done();
}, 3000);
});


As per code coverage results, this.router.navigate(["/success"]); is being covered by callback().
But "should route on callback" test is failing as routerSpy.navigate is never being called.



Why?










share|improve this question





























    1















    I want to test this.communication.subscribe() call which is having a callback in argument:



    constructor (private communication: CommunicationProvider)

    ngOnInit() {
    this.communication.subscribe(() => {
    this.router.navigate(["/success"]);
    });
    }


    I have used callFake to mock the implementation to call callback()



    beforeEach(async(() => {
    communicationSpy = jasmine.createSpyObj("CommunicationProvider", ["subscribe"]);
    routerSpy = jasmine.createSpyObj<Router>("Router", ["navigate"]);

    communicationSpy.subscribe.and.callFake((callback: any) => {
    callback();
    });
    }));

    it("should route on callback", (done: DoneFn) => {
    setTimeout(() => {
    expect(routerSpy.navigate).toHaveBeenCalledWith(["/success"]);
    done();
    }, 3000);
    });


    As per code coverage results, this.router.navigate(["/success"]); is being covered by callback().
    But "should route on callback" test is failing as routerSpy.navigate is never being called.



    Why?










    share|improve this question



























      1












      1








      1








      I want to test this.communication.subscribe() call which is having a callback in argument:



      constructor (private communication: CommunicationProvider)

      ngOnInit() {
      this.communication.subscribe(() => {
      this.router.navigate(["/success"]);
      });
      }


      I have used callFake to mock the implementation to call callback()



      beforeEach(async(() => {
      communicationSpy = jasmine.createSpyObj("CommunicationProvider", ["subscribe"]);
      routerSpy = jasmine.createSpyObj<Router>("Router", ["navigate"]);

      communicationSpy.subscribe.and.callFake((callback: any) => {
      callback();
      });
      }));

      it("should route on callback", (done: DoneFn) => {
      setTimeout(() => {
      expect(routerSpy.navigate).toHaveBeenCalledWith(["/success"]);
      done();
      }, 3000);
      });


      As per code coverage results, this.router.navigate(["/success"]); is being covered by callback().
      But "should route on callback" test is failing as routerSpy.navigate is never being called.



      Why?










      share|improve this question
















      I want to test this.communication.subscribe() call which is having a callback in argument:



      constructor (private communication: CommunicationProvider)

      ngOnInit() {
      this.communication.subscribe(() => {
      this.router.navigate(["/success"]);
      });
      }


      I have used callFake to mock the implementation to call callback()



      beforeEach(async(() => {
      communicationSpy = jasmine.createSpyObj("CommunicationProvider", ["subscribe"]);
      routerSpy = jasmine.createSpyObj<Router>("Router", ["navigate"]);

      communicationSpy.subscribe.and.callFake((callback: any) => {
      callback();
      });
      }));

      it("should route on callback", (done: DoneFn) => {
      setTimeout(() => {
      expect(routerSpy.navigate).toHaveBeenCalledWith(["/success"]);
      done();
      }, 3000);
      });


      As per code coverage results, this.router.navigate(["/success"]); is being covered by callback().
      But "should route on callback" test is failing as routerSpy.navigate is never being called.



      Why?







      angular typescript unit-testing callback jasmine






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 22 '18 at 13:13









      trichetriche

      26k42152




      26k42152










      asked Nov 22 '18 at 13:02









      bhagatbhagat

      618




      618
























          1 Answer
          1






          active

          oldest

          votes


















          0














          Because you never trigger the subscription.



          I don't know what your service is, but we'll take advantage of the fact that you don't use restriction operators such as take or takeUntil.



          Start by mocking your observable as a hot stream with a Subject :



          component['communication'] = new Subject() as any;


          Now, you should have a new instance of your component in every test thanks to the fixture createComponentInstance called in the before each. This means you already have called ngOnInit and created the subscription.



          Since the stream is hot, you can subscribe to it in your test :



          it('should navigate', done => {
          component['communication'].subscribe(() => {
          expect(routerSpy.navigate).toHaveBeenCalledWith(["/success"]);
          done();
          });

          (component['communication'] as Subject).next(true);
          });


          With the next call, you trigger the subscriptions, launching the router and expecting it to have been called.



          (P.S : I have used array syntax and Subject to picture the issue, feel free to use whatever you want to trigger a subscription and to mock your dependencies)






          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%2f53431649%2fwhy-jasmine-spy-function-in-angular-is-not-being-triggered-by-callback%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














            Because you never trigger the subscription.



            I don't know what your service is, but we'll take advantage of the fact that you don't use restriction operators such as take or takeUntil.



            Start by mocking your observable as a hot stream with a Subject :



            component['communication'] = new Subject() as any;


            Now, you should have a new instance of your component in every test thanks to the fixture createComponentInstance called in the before each. This means you already have called ngOnInit and created the subscription.



            Since the stream is hot, you can subscribe to it in your test :



            it('should navigate', done => {
            component['communication'].subscribe(() => {
            expect(routerSpy.navigate).toHaveBeenCalledWith(["/success"]);
            done();
            });

            (component['communication'] as Subject).next(true);
            });


            With the next call, you trigger the subscriptions, launching the router and expecting it to have been called.



            (P.S : I have used array syntax and Subject to picture the issue, feel free to use whatever you want to trigger a subscription and to mock your dependencies)






            share|improve this answer




























              0














              Because you never trigger the subscription.



              I don't know what your service is, but we'll take advantage of the fact that you don't use restriction operators such as take or takeUntil.



              Start by mocking your observable as a hot stream with a Subject :



              component['communication'] = new Subject() as any;


              Now, you should have a new instance of your component in every test thanks to the fixture createComponentInstance called in the before each. This means you already have called ngOnInit and created the subscription.



              Since the stream is hot, you can subscribe to it in your test :



              it('should navigate', done => {
              component['communication'].subscribe(() => {
              expect(routerSpy.navigate).toHaveBeenCalledWith(["/success"]);
              done();
              });

              (component['communication'] as Subject).next(true);
              });


              With the next call, you trigger the subscriptions, launching the router and expecting it to have been called.



              (P.S : I have used array syntax and Subject to picture the issue, feel free to use whatever you want to trigger a subscription and to mock your dependencies)






              share|improve this answer


























                0












                0








                0







                Because you never trigger the subscription.



                I don't know what your service is, but we'll take advantage of the fact that you don't use restriction operators such as take or takeUntil.



                Start by mocking your observable as a hot stream with a Subject :



                component['communication'] = new Subject() as any;


                Now, you should have a new instance of your component in every test thanks to the fixture createComponentInstance called in the before each. This means you already have called ngOnInit and created the subscription.



                Since the stream is hot, you can subscribe to it in your test :



                it('should navigate', done => {
                component['communication'].subscribe(() => {
                expect(routerSpy.navigate).toHaveBeenCalledWith(["/success"]);
                done();
                });

                (component['communication'] as Subject).next(true);
                });


                With the next call, you trigger the subscriptions, launching the router and expecting it to have been called.



                (P.S : I have used array syntax and Subject to picture the issue, feel free to use whatever you want to trigger a subscription and to mock your dependencies)






                share|improve this answer













                Because you never trigger the subscription.



                I don't know what your service is, but we'll take advantage of the fact that you don't use restriction operators such as take or takeUntil.



                Start by mocking your observable as a hot stream with a Subject :



                component['communication'] = new Subject() as any;


                Now, you should have a new instance of your component in every test thanks to the fixture createComponentInstance called in the before each. This means you already have called ngOnInit and created the subscription.



                Since the stream is hot, you can subscribe to it in your test :



                it('should navigate', done => {
                component['communication'].subscribe(() => {
                expect(routerSpy.navigate).toHaveBeenCalledWith(["/success"]);
                done();
                });

                (component['communication'] as Subject).next(true);
                });


                With the next call, you trigger the subscriptions, launching the router and expecting it to have been called.



                (P.S : I have used array syntax and Subject to picture the issue, feel free to use whatever you want to trigger a subscription and to mock your dependencies)







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 22 '18 at 13:12









                trichetrichetrichetriche

                26k42152




                26k42152






























                    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%2f53431649%2fwhy-jasmine-spy-function-in-angular-is-not-being-triggered-by-callback%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

                    404 Error Contact Form 7 ajax form submitting

                    How to know if a Active Directory user can login interactively

                    TypeError: fit_transform() missing 1 required positional argument: 'X'