首页 > 解决方案 > Unit test multiple calls to same function with different arguments angularjs/jasmine

问题描述

I am trying to test similar piece of code.

What it does is when I get 409 it changes the argument and calls the same function again.

function testSomething(stuff) {
  console.log(stuff);
  return customService.doSomething().then(function() {
    return customService.doSomethingElse().then(function(something) {
      //do something here
      return $q.resolve(something);
    });
  }, function(error) {
    if(error.status === 409) {
      //change stuff
      //something like stuff = newStuff;
      testSomething(stuff);
    }
  });
}

So I am trying to check function arguments when its called 1st and 2nd time. But when arguments for 2nd call are showing undefined. And also the assert toHaveBeenCallTimes 2 fails.

it('should handle 409', function() {
  spyOn(customService, 'doSomething').and.returnValue($q.reject({
    status: 409
  }));
  spyOn(someService, 'testSomething').and.callThrough();
  
  someService.testSomething(stuff);
  $scope.$apply();

  expect(someService.testSomething.calls.argsFor[0]).toEqual([stuff]);
  expect(customService.doSomething).toHaveBeenCalled();
  expect(someService.testSomething.calls.argsFor[1]).toEqual([newStuff]);
  expect(someService.testSomething).toHaveBeenCalledTimes(2);
});

Although I can see console.log(stuff) logging 2 times in the console with correct arguments.

标签: angularjsjasminejasmine2.0

解决方案


我猜你的间谍只是互相覆盖。你可以这样做:

spyOn(customService, 'doSomething').and.returnValue($q.reject({
    status: 409
  }));
  someService.testSomething(stuff);
  // now doSomething is called and $q.reject is retuend
  expect(someService.testSomething.calls.argsFor[0]).toEqual([stuff]);      

  spyOn(customService, 'doSomething').and.returnValue($q.when());
  $scope.$apply();

或者像这样,我更喜欢:

var index = 0;

spyOn(customService, 'doSomething').and.callFake(() => {
  index++;
  return index === 1 ? $q.reject({status: 409}) : $q.when();
});

推荐阅读