有没有办法根据参数修改Jasmine间谍?

Jmr*_*Jmr 129 javascript unit-testing jasmine

我有一个函数我想测试哪个调用外部API方法两次,使用不同的参数.我想用Jasmine间谍模拟这个外部API,并根据参数返回不同的东西.在Jasmine有什么办法吗?我能想到的最好的是使用andCallFake的hack:

var functionToTest = function() {
  var userName = externalApi.get('abc');
  var userId = externalApi.get('123');
};


describe('my fn', function() {
  it('gets user name and ID', function() {
    spyOn(externalApi, 'get').andCallFake(function(myParam) {
      if (myParam == 'abc') {
        return 'Jane';
      } else if (myParam == '123') {
        return 98765;
      }
    });
  });
});
Run Code Online (Sandbox Code Playgroud)

And*_*rle 183

在Jasmine 3.0及以上版本中,您可以使用 withArgs

describe('my fn', function() {
  it('gets user name and ID', function() {
    spyOn(externalApi, 'get')
      .withArgs('abc').and.returnValue('Jane')
      .withArgs('123').and.returnValue(98765);
  });
});
Run Code Online (Sandbox Code Playgroud)

对于早于3.0的Jasmine版本callFake是正确的方法,但您可以使用对象来简化它以保存返回值

describe('my fn', function() {
  var params = {
    'abc': 'Jane', 
    '123': 98765
  }

  it('gets user name and ID', function() {
    spyOn(externalApi, 'get').and.callFake(function(myParam) {
     return params[myParam]
    });
  });
});
Run Code Online (Sandbox Code Playgroud)

根据Jasmine的版本,语法略有不同:

  • 1.3.1: .andCallFake(fn)
  • 2.0: .and.callFake(fn)

资源:

  • 现在是`and.callFake` - http://jasmine.github.io/2.2/introduction.html#section-Spies:_ <code> and.callFake </ code> (11认同)
  • 感觉像茉莉花应该有一个更好的方式来宣布这一点.比如`spyOn(假,'方法').withArgs('abc').和.returnValue('Jane')`和`spyOn(假,'方法').withArgs('123').and.returnValue(98765 )`. (7认同)

akh*_*uri 8

您还可以使用$provide创建间谍.并模拟使用and.returnValues而不是and.returnValue传递参数化数据.

根据Jasmine docs:通过链接间谍and.returnValues,对函数的所有调用将按顺序返回特定值,直到它到达返回值列表的末尾,此时它将为所有后续调用返回undefined.

describe('my fn', () => {
    beforeEach(module($provide => {
        $provide.value('externalApi', jasmine.createSpyObj('externalApi', ['get']));
    }));

        it('get userName and Id', inject((externalApi) => {
            // Given
            externalApi.get.and.returnValues('abc','123');

            // When
            //insert your condition

            // Then
            // insert the expectation                
        }));
});
Run Code Online (Sandbox Code Playgroud)

  • 只是为了澄清akhouri的答案:仅当在`it`函数中调用了`externalApi.get.and.returnValues('abc','123')`时,此方法才有效。否则,如果您在其他地方设置了值列表,则它将永远无法工作,因为运行测试的顺序是不可预测的。实际上,测试不应依赖于执行顺序。 (2认同)