Jasmine 测试连续 Promise 调用

Jasmine Test Consecutive Promise Calls

我有以下测试执行以下操作:

  1. 进行模拟服务调用,returns 承诺解析为某些货币代码。
  2. 断言在控制器范围内设置的货币代码与模拟服务返回的货币代码相匹配。
  3. 第二次模拟服务调用导致错误。
  4. 断言控制器作用域上设置的货币代码为空。

第 2 步的断言失败,因为货币代码为空。似乎我无法在测试中对承诺进行排序。代码如下:

    beforeEach(inject(function($rootScope, $controller, $log, $q) {
        //.....
        spyOn(clientMoneyService, findCurrencyCodes').andReturn(deferral.promise);
}));

it('should clear currency codes on error', inject(function() {
    scope.findCurrencyCodes();
    // first call returns currencies
    deferral.resolve(response);
    var response = {
        data: ['AUD', 'CAD']
    };
    scope.$apply();
    expect(scope.currencyCodes).toEqual(['AUD', 'CAD']);

    // second call errors out
    deferral.reject();
    scope.findCurrencyCodes();
    scope.$apply();
    expect(scope.currencyCodes).toBeNull();
}));

有没有一种方法可以对我的承诺进行排序,以便在第一次调用时我得到一个货币代码列表,而在第二次调用时我得到一个错误?

任何给定的 promise 只能用于 return 一个结果(无论是解决还是拒绝),因此在解决它之后尝试拒绝 promise 是行不通的。测试您的方法的最简单方法是将您的测试分成两个,每个结果一个:

it('should resolve to currency codes on success', function() {
  scope.findCurrencyCodes();      
  deferral.resolve({data: ['AUD', 'CAD']});
  scope.$digest();
  expect(scope.currencyCodes).toEqual(['AUD', 'CAD']);
});

it('should clear currency codes on error', function() {     
  scope.currencyCodes = ['AUD', 'CAD'];
  scope.findCurrencyCodes();
  deferral.reject();
  scope.$digest();
  expect(scope.currencyCodes).toBeNull();
});

如果由于某种原因你真的必须在同一个测试中断言这两个,你需要修改你的存根 findCurrencyCodes 到 return 每次调用时都是一个新的承诺。