1

I am new in unit testing with Jasmine in Angular.

I am currently testing a service that has a function called loadSomething(id) and I have added a console.info in it.

MY SERVICE:

function loadSomething(id)
{
    console.info('this is a test message');
    return (a promise from a POST request)
}

And this is my test (spec) file:

//verify that the load function exists
it('load snapshot',function(){

  expect(MyService.loadSomething(108)); //statement 1
  spyOn(MyService, 'loadSomething').and.callThrough(); //statement 2
});

So, I read online that the callthrough method of SpyOn calls the ACTUAL function. However, when i run my test with the expect statement (statement 1) the console.info message is invoked (that works fine). On the other hand, when I comment out statement 1 and uncomment the SpyOn(statement 2) I do not get the console.info message anymore.

I would expect the exact opposite to happen. Have I understood something wrong here?

(the rest of the code works fine, both the spec file and the actual service, I just don't really get this specific thing)

A-Sharabiani
  • 17,750
  • 17
  • 113
  • 128
user2998261
  • 11
  • 1
  • 1
  • 3

1 Answers1

1

The SpyOn will help you to setup how the function should react when it's being called upon in your tests. Basically it's jasmines way of creating mocks.

In your case you have defined what the test should do when the service function is being called, which is callThrough. The problem is that you also need to act on the service function (or the scope function which calls your service method) in order to trigger the SpyOn which will callThrough

it('load snapshot',function(){

  //setup
  spyOn(MyService, 'loadSomething').and.callThrough(); //statement 2

  //act

  //either call the scope function which uses the service 
  //$scope.yourServiceCallFunction();

  //or call the service function directly
  MyService.loadSomething(1); //this will callThrough

});

Here's an simple test where we will mock the response of the SpyOn to a string

it('test loadSomething',function(){

  //setup
  spyOn(MyService, 'loadSomething').and.returnValue('Mocked');

  //act
  var val = MyService.loadSomething(1);

  //check
  expect(val).toEqual('Mocked');
});
Marcus Höglund
  • 16,172
  • 11
  • 47
  • 69
  • 1
    you say "this will call through". but what does calling through mean? I expected it to be something like this: function a(){ b(); } function b() { c(); } function c() { console.log('called through all the way to this one'); }. So when I would say spyOn(MyService, 'a').and.callThrough(); and then MyService.a(), I would expect to see teh console log, because I told it to call through all the chain. but I have a feeling that's not what they intended by the wording... – bokkie Apr 29 '21 at 08:39
  • From the documentation: "By chaining the spy with and.callThrough, the spy will still track all calls to it but in addition it will delegate to the actual implementation." – Bishares Jan 18 '23 at 15:06