method being spied not getting called - Expected spy show to have been called










0















I have a sendMessage method which calls another service (LoaderService) show method.



sendMessage(url:string, body:any,httpOptions):Observable<HttpEvent<any>> 
this.loaderService.show();
... //IT DOES OTHER THINGS AS WELL BUT THAT ISN'T WHAT I AM TESTING



I am trying to test that the show method is called but I am getting error Expected spy show to have been called.. What I might be doing wrong? In my opinion, show should get called because it is the first line in sendMessage.



The spec is



describe('sendMessage function test suite: ',()=> 
let loader: LoaderService;
let httpClient:HttpClient;
let spy:any;
const httpOptions =
headers: new HttpHeaders('Content-Type': 'application/json'),
withCredentials: true,
observe: 'events',
responseType: 'json'
;


beforeEach(() =>
TestBed.configureTestingModule(
providers: [HelperService, HttpClient, HttpHandler,LoaderService],
imports: [ReactiveFormsModule, HttpClientModule, HttpClientTestingModule]
);
);

fit('should show loader/spinner',
inject([HttpTestingController,HelperService,HttpClient,LoaderService],(httpClient:HttpClient,httpMock:HttpTestingController)=>
const responseData = result: 'success', ['additional-info']: 'some data from server' ;

loader = new LoaderService();
spyOn(loader,'show'); //sendMessage calls show method of loader.
let httpEvent:HttpResponse<any> = new HttpResponse<any>(body:responseData);
let helperService = TestBed.get(HelperService);
let result:Observable<HttpEvent<any>> = helperService.sendMessage('/someURL','someBody',httpOptions);
let subscription = result.subscribe((event:HttpEvent<any>)=>
console.log('got response ',event);
);
expect(loader.show).toHaveBeenCalled();
));
);









share|improve this question






















  • Clarification question -- is "TestBed.configureTestingModule" from Angular6?

    – RoboBear
    Nov 14 '18 at 18:05











  • I suppose so. I am using Angular6

    – Manu Chadha
    Nov 14 '18 at 18:48















0















I have a sendMessage method which calls another service (LoaderService) show method.



sendMessage(url:string, body:any,httpOptions):Observable<HttpEvent<any>> 
this.loaderService.show();
... //IT DOES OTHER THINGS AS WELL BUT THAT ISN'T WHAT I AM TESTING



I am trying to test that the show method is called but I am getting error Expected spy show to have been called.. What I might be doing wrong? In my opinion, show should get called because it is the first line in sendMessage.



The spec is



describe('sendMessage function test suite: ',()=> 
let loader: LoaderService;
let httpClient:HttpClient;
let spy:any;
const httpOptions =
headers: new HttpHeaders('Content-Type': 'application/json'),
withCredentials: true,
observe: 'events',
responseType: 'json'
;


beforeEach(() =>
TestBed.configureTestingModule(
providers: [HelperService, HttpClient, HttpHandler,LoaderService],
imports: [ReactiveFormsModule, HttpClientModule, HttpClientTestingModule]
);
);

fit('should show loader/spinner',
inject([HttpTestingController,HelperService,HttpClient,LoaderService],(httpClient:HttpClient,httpMock:HttpTestingController)=>
const responseData = result: 'success', ['additional-info']: 'some data from server' ;

loader = new LoaderService();
spyOn(loader,'show'); //sendMessage calls show method of loader.
let httpEvent:HttpResponse<any> = new HttpResponse<any>(body:responseData);
let helperService = TestBed.get(HelperService);
let result:Observable<HttpEvent<any>> = helperService.sendMessage('/someURL','someBody',httpOptions);
let subscription = result.subscribe((event:HttpEvent<any>)=>
console.log('got response ',event);
);
expect(loader.show).toHaveBeenCalled();
));
);









share|improve this question






















  • Clarification question -- is "TestBed.configureTestingModule" from Angular6?

    – RoboBear
    Nov 14 '18 at 18:05











  • I suppose so. I am using Angular6

    – Manu Chadha
    Nov 14 '18 at 18:48













0












0








0








I have a sendMessage method which calls another service (LoaderService) show method.



sendMessage(url:string, body:any,httpOptions):Observable<HttpEvent<any>> 
this.loaderService.show();
... //IT DOES OTHER THINGS AS WELL BUT THAT ISN'T WHAT I AM TESTING



I am trying to test that the show method is called but I am getting error Expected spy show to have been called.. What I might be doing wrong? In my opinion, show should get called because it is the first line in sendMessage.



The spec is



describe('sendMessage function test suite: ',()=> 
let loader: LoaderService;
let httpClient:HttpClient;
let spy:any;
const httpOptions =
headers: new HttpHeaders('Content-Type': 'application/json'),
withCredentials: true,
observe: 'events',
responseType: 'json'
;


beforeEach(() =>
TestBed.configureTestingModule(
providers: [HelperService, HttpClient, HttpHandler,LoaderService],
imports: [ReactiveFormsModule, HttpClientModule, HttpClientTestingModule]
);
);

fit('should show loader/spinner',
inject([HttpTestingController,HelperService,HttpClient,LoaderService],(httpClient:HttpClient,httpMock:HttpTestingController)=>
const responseData = result: 'success', ['additional-info']: 'some data from server' ;

loader = new LoaderService();
spyOn(loader,'show'); //sendMessage calls show method of loader.
let httpEvent:HttpResponse<any> = new HttpResponse<any>(body:responseData);
let helperService = TestBed.get(HelperService);
let result:Observable<HttpEvent<any>> = helperService.sendMessage('/someURL','someBody',httpOptions);
let subscription = result.subscribe((event:HttpEvent<any>)=>
console.log('got response ',event);
);
expect(loader.show).toHaveBeenCalled();
));
);









share|improve this question














I have a sendMessage method which calls another service (LoaderService) show method.



sendMessage(url:string, body:any,httpOptions):Observable<HttpEvent<any>> 
this.loaderService.show();
... //IT DOES OTHER THINGS AS WELL BUT THAT ISN'T WHAT I AM TESTING



I am trying to test that the show method is called but I am getting error Expected spy show to have been called.. What I might be doing wrong? In my opinion, show should get called because it is the first line in sendMessage.



The spec is



describe('sendMessage function test suite: ',()=> 
let loader: LoaderService;
let httpClient:HttpClient;
let spy:any;
const httpOptions =
headers: new HttpHeaders('Content-Type': 'application/json'),
withCredentials: true,
observe: 'events',
responseType: 'json'
;


beforeEach(() =>
TestBed.configureTestingModule(
providers: [HelperService, HttpClient, HttpHandler,LoaderService],
imports: [ReactiveFormsModule, HttpClientModule, HttpClientTestingModule]
);
);

fit('should show loader/spinner',
inject([HttpTestingController,HelperService,HttpClient,LoaderService],(httpClient:HttpClient,httpMock:HttpTestingController)=>
const responseData = result: 'success', ['additional-info']: 'some data from server' ;

loader = new LoaderService();
spyOn(loader,'show'); //sendMessage calls show method of loader.
let httpEvent:HttpResponse<any> = new HttpResponse<any>(body:responseData);
let helperService = TestBed.get(HelperService);
let result:Observable<HttpEvent<any>> = helperService.sendMessage('/someURL','someBody',httpOptions);
let subscription = result.subscribe((event:HttpEvent<any>)=>
console.log('got response ',event);
);
expect(loader.show).toHaveBeenCalled();
));
);






jasmine angular6






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 14 '18 at 17:28









Manu ChadhaManu Chadha

3,40721945




3,40721945












  • Clarification question -- is "TestBed.configureTestingModule" from Angular6?

    – RoboBear
    Nov 14 '18 at 18:05











  • I suppose so. I am using Angular6

    – Manu Chadha
    Nov 14 '18 at 18:48

















  • Clarification question -- is "TestBed.configureTestingModule" from Angular6?

    – RoboBear
    Nov 14 '18 at 18:05











  • I suppose so. I am using Angular6

    – Manu Chadha
    Nov 14 '18 at 18:48
















Clarification question -- is "TestBed.configureTestingModule" from Angular6?

– RoboBear
Nov 14 '18 at 18:05





Clarification question -- is "TestBed.configureTestingModule" from Angular6?

– RoboBear
Nov 14 '18 at 18:05













I suppose so. I am using Angular6

– Manu Chadha
Nov 14 '18 at 18:48





I suppose so. I am using Angular6

– Manu Chadha
Nov 14 '18 at 18:48












2 Answers
2






active

oldest

votes


















0














You spy on another instance of LoaderService. The spyOn function is used to install a spy into the object, not globally.



You can get the same instance that is injected to the HelperService using TestBed.get(LoaderService).



Please refer to this Testing - Component with a dependency document.






share|improve this answer






























    0














    Mixth's explanation above is correct. Following are my observations which I thought I should share.



    I suppose I was doing few things wrong in my the previous code. As far as I know, there are 3 ways I could test



    1) Use only Jasmine and Karma without using Testbed. this is a generic approach. I explicitly create instances of the classes I need in this approach. For eg.



    new LoaderService().



    The above works well for my own defined classes (services and components). But if my test case uses some Angular's modules (eg HttpClientModule) then it is better to use TestBed - "Testbed is a very Angular specific functionality whichh would take care of instantiating components, services and taking care of dependencies using DI"



    To ensure that the test case is referring to the same instance of a class all the time, TestBed should be used extract instances of all the classes.



    fit('should show loader/spinner',()=>
    let helperService = TestBed.get(HelperService);//extract helper service
    let loaderService = TestBed.get(LoaderService);//extract Loader Service. As I am using TestBed, I'll get the same instance of LoaderService which Angular would have used to create HelperrService
    spyOn(loaderService,'show'); //sendMessage calls hide method of loader.

    const responseData = result: 'success', ['additional-info']: 'some data from server' ;
    let httpEvent:HttpResponse<any> = new HttpResponse<any>(body:responseData);
    /*HttpTestingController to be injected into tests, that allows for mocking and flushing of requests.
    HttpTestingController has methods which could mock sending a request
    */
    let httpMock = TestBed.get(HttpTestingController);
    //call the sendMessage function and subscribe to its observable.
    let result:Observable<HttpEvent<any>> = helperService.sendMessage('/someURL','someBody',httpOptions);
    let subscription = result.subscribe((event:HttpEvent<any>)=>
    console.log('got response ',event);
    );
    const mockReq:TestRequest = httpMock.expectOne('/someURL'); //Expect that a single request has been made which matches the given URL, and return its mock
    //once mocking of sending request is done, mock receiving a response. This will trigger the logic inside subscribe function
    mockReq.flush(httpEvent); //flush method provides dummy values as response

    httpMock.verify();//verify checks that there are no outstanding requests;

    expect(loaderService.show).toHaveBeenCalled(); //check that the loader show is called which in real application will show a progress bar
    );





    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%2f53305743%2fmethod-being-spied-not-getting-called-expected-spy-show-to-have-been-called%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      0














      You spy on another instance of LoaderService. The spyOn function is used to install a spy into the object, not globally.



      You can get the same instance that is injected to the HelperService using TestBed.get(LoaderService).



      Please refer to this Testing - Component with a dependency document.






      share|improve this answer



























        0














        You spy on another instance of LoaderService. The spyOn function is used to install a spy into the object, not globally.



        You can get the same instance that is injected to the HelperService using TestBed.get(LoaderService).



        Please refer to this Testing - Component with a dependency document.






        share|improve this answer

























          0












          0








          0







          You spy on another instance of LoaderService. The spyOn function is used to install a spy into the object, not globally.



          You can get the same instance that is injected to the HelperService using TestBed.get(LoaderService).



          Please refer to this Testing - Component with a dependency document.






          share|improve this answer













          You spy on another instance of LoaderService. The spyOn function is used to install a spy into the object, not globally.



          You can get the same instance that is injected to the HelperService using TestBed.get(LoaderService).



          Please refer to this Testing - Component with a dependency document.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 15 '18 at 5:31









          mixthmixth

          451511




          451511























              0














              Mixth's explanation above is correct. Following are my observations which I thought I should share.



              I suppose I was doing few things wrong in my the previous code. As far as I know, there are 3 ways I could test



              1) Use only Jasmine and Karma without using Testbed. this is a generic approach. I explicitly create instances of the classes I need in this approach. For eg.



              new LoaderService().



              The above works well for my own defined classes (services and components). But if my test case uses some Angular's modules (eg HttpClientModule) then it is better to use TestBed - "Testbed is a very Angular specific functionality whichh would take care of instantiating components, services and taking care of dependencies using DI"



              To ensure that the test case is referring to the same instance of a class all the time, TestBed should be used extract instances of all the classes.



              fit('should show loader/spinner',()=>
              let helperService = TestBed.get(HelperService);//extract helper service
              let loaderService = TestBed.get(LoaderService);//extract Loader Service. As I am using TestBed, I'll get the same instance of LoaderService which Angular would have used to create HelperrService
              spyOn(loaderService,'show'); //sendMessage calls hide method of loader.

              const responseData = result: 'success', ['additional-info']: 'some data from server' ;
              let httpEvent:HttpResponse<any> = new HttpResponse<any>(body:responseData);
              /*HttpTestingController to be injected into tests, that allows for mocking and flushing of requests.
              HttpTestingController has methods which could mock sending a request
              */
              let httpMock = TestBed.get(HttpTestingController);
              //call the sendMessage function and subscribe to its observable.
              let result:Observable<HttpEvent<any>> = helperService.sendMessage('/someURL','someBody',httpOptions);
              let subscription = result.subscribe((event:HttpEvent<any>)=>
              console.log('got response ',event);
              );
              const mockReq:TestRequest = httpMock.expectOne('/someURL'); //Expect that a single request has been made which matches the given URL, and return its mock
              //once mocking of sending request is done, mock receiving a response. This will trigger the logic inside subscribe function
              mockReq.flush(httpEvent); //flush method provides dummy values as response

              httpMock.verify();//verify checks that there are no outstanding requests;

              expect(loaderService.show).toHaveBeenCalled(); //check that the loader show is called which in real application will show a progress bar
              );





              share|improve this answer



























                0














                Mixth's explanation above is correct. Following are my observations which I thought I should share.



                I suppose I was doing few things wrong in my the previous code. As far as I know, there are 3 ways I could test



                1) Use only Jasmine and Karma without using Testbed. this is a generic approach. I explicitly create instances of the classes I need in this approach. For eg.



                new LoaderService().



                The above works well for my own defined classes (services and components). But if my test case uses some Angular's modules (eg HttpClientModule) then it is better to use TestBed - "Testbed is a very Angular specific functionality whichh would take care of instantiating components, services and taking care of dependencies using DI"



                To ensure that the test case is referring to the same instance of a class all the time, TestBed should be used extract instances of all the classes.



                fit('should show loader/spinner',()=>
                let helperService = TestBed.get(HelperService);//extract helper service
                let loaderService = TestBed.get(LoaderService);//extract Loader Service. As I am using TestBed, I'll get the same instance of LoaderService which Angular would have used to create HelperrService
                spyOn(loaderService,'show'); //sendMessage calls hide method of loader.

                const responseData = result: 'success', ['additional-info']: 'some data from server' ;
                let httpEvent:HttpResponse<any> = new HttpResponse<any>(body:responseData);
                /*HttpTestingController to be injected into tests, that allows for mocking and flushing of requests.
                HttpTestingController has methods which could mock sending a request
                */
                let httpMock = TestBed.get(HttpTestingController);
                //call the sendMessage function and subscribe to its observable.
                let result:Observable<HttpEvent<any>> = helperService.sendMessage('/someURL','someBody',httpOptions);
                let subscription = result.subscribe((event:HttpEvent<any>)=>
                console.log('got response ',event);
                );
                const mockReq:TestRequest = httpMock.expectOne('/someURL'); //Expect that a single request has been made which matches the given URL, and return its mock
                //once mocking of sending request is done, mock receiving a response. This will trigger the logic inside subscribe function
                mockReq.flush(httpEvent); //flush method provides dummy values as response

                httpMock.verify();//verify checks that there are no outstanding requests;

                expect(loaderService.show).toHaveBeenCalled(); //check that the loader show is called which in real application will show a progress bar
                );





                share|improve this answer

























                  0












                  0








                  0







                  Mixth's explanation above is correct. Following are my observations which I thought I should share.



                  I suppose I was doing few things wrong in my the previous code. As far as I know, there are 3 ways I could test



                  1) Use only Jasmine and Karma without using Testbed. this is a generic approach. I explicitly create instances of the classes I need in this approach. For eg.



                  new LoaderService().



                  The above works well for my own defined classes (services and components). But if my test case uses some Angular's modules (eg HttpClientModule) then it is better to use TestBed - "Testbed is a very Angular specific functionality whichh would take care of instantiating components, services and taking care of dependencies using DI"



                  To ensure that the test case is referring to the same instance of a class all the time, TestBed should be used extract instances of all the classes.



                  fit('should show loader/spinner',()=>
                  let helperService = TestBed.get(HelperService);//extract helper service
                  let loaderService = TestBed.get(LoaderService);//extract Loader Service. As I am using TestBed, I'll get the same instance of LoaderService which Angular would have used to create HelperrService
                  spyOn(loaderService,'show'); //sendMessage calls hide method of loader.

                  const responseData = result: 'success', ['additional-info']: 'some data from server' ;
                  let httpEvent:HttpResponse<any> = new HttpResponse<any>(body:responseData);
                  /*HttpTestingController to be injected into tests, that allows for mocking and flushing of requests.
                  HttpTestingController has methods which could mock sending a request
                  */
                  let httpMock = TestBed.get(HttpTestingController);
                  //call the sendMessage function and subscribe to its observable.
                  let result:Observable<HttpEvent<any>> = helperService.sendMessage('/someURL','someBody',httpOptions);
                  let subscription = result.subscribe((event:HttpEvent<any>)=>
                  console.log('got response ',event);
                  );
                  const mockReq:TestRequest = httpMock.expectOne('/someURL'); //Expect that a single request has been made which matches the given URL, and return its mock
                  //once mocking of sending request is done, mock receiving a response. This will trigger the logic inside subscribe function
                  mockReq.flush(httpEvent); //flush method provides dummy values as response

                  httpMock.verify();//verify checks that there are no outstanding requests;

                  expect(loaderService.show).toHaveBeenCalled(); //check that the loader show is called which in real application will show a progress bar
                  );





                  share|improve this answer













                  Mixth's explanation above is correct. Following are my observations which I thought I should share.



                  I suppose I was doing few things wrong in my the previous code. As far as I know, there are 3 ways I could test



                  1) Use only Jasmine and Karma without using Testbed. this is a generic approach. I explicitly create instances of the classes I need in this approach. For eg.



                  new LoaderService().



                  The above works well for my own defined classes (services and components). But if my test case uses some Angular's modules (eg HttpClientModule) then it is better to use TestBed - "Testbed is a very Angular specific functionality whichh would take care of instantiating components, services and taking care of dependencies using DI"



                  To ensure that the test case is referring to the same instance of a class all the time, TestBed should be used extract instances of all the classes.



                  fit('should show loader/spinner',()=>
                  let helperService = TestBed.get(HelperService);//extract helper service
                  let loaderService = TestBed.get(LoaderService);//extract Loader Service. As I am using TestBed, I'll get the same instance of LoaderService which Angular would have used to create HelperrService
                  spyOn(loaderService,'show'); //sendMessage calls hide method of loader.

                  const responseData = result: 'success', ['additional-info']: 'some data from server' ;
                  let httpEvent:HttpResponse<any> = new HttpResponse<any>(body:responseData);
                  /*HttpTestingController to be injected into tests, that allows for mocking and flushing of requests.
                  HttpTestingController has methods which could mock sending a request
                  */
                  let httpMock = TestBed.get(HttpTestingController);
                  //call the sendMessage function and subscribe to its observable.
                  let result:Observable<HttpEvent<any>> = helperService.sendMessage('/someURL','someBody',httpOptions);
                  let subscription = result.subscribe((event:HttpEvent<any>)=>
                  console.log('got response ',event);
                  );
                  const mockReq:TestRequest = httpMock.expectOne('/someURL'); //Expect that a single request has been made which matches the given URL, and return its mock
                  //once mocking of sending request is done, mock receiving a response. This will trigger the logic inside subscribe function
                  mockReq.flush(httpEvent); //flush method provides dummy values as response

                  httpMock.verify();//verify checks that there are no outstanding requests;

                  expect(loaderService.show).toHaveBeenCalled(); //check that the loader show is called which in real application will show a progress bar
                  );






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 16 '18 at 5:31









                  Manu ChadhaManu Chadha

                  3,40721945




                  3,40721945



























                      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%2f53305743%2fmethod-being-spied-not-getting-called-expected-spy-show-to-have-been-called%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

                      How to how show current date and time by default on contact form 7 in WordPress without taking input from user in datetimepicker

                      Darth Vader #20

                      Ondo