单元测试依赖于服务的角度过滤器

Unit testing Angular filter which relies on service

本文关键字:过滤器 依赖于 服务 单元测试      更新时间:2023-09-26

我正在尝试测试我构建的自定义过滤器。我遇到的问题是此过滤器依赖于通过服务的异步调用。下面是我的相关过滤器代码,然后是我当前的测试:

.filter('formatValue', ['serverService', '_', function(serverService, _) {
  var available = null;
  var serviceInvoked = false;
  function formatValue(value, code) {
    var details = _.findWhere(available, {code: code});
    if (details) {
      return details.unitSymbol + parts.join('.');
    } else {
      return value;
    }
  }
  getAvailable.$stateful = true;
  function getAvailable(value, code) {
    if (available === null) {
      if (!serviceInvoked) {
        serviceInvoked = true;
        serverService.getAvailable().$promise.then(function(data) {
          available = data;
        });
      }
    } else {
      return formatValue(value, code);
    }
  }
  return getAvailable;
}])

测试:

describe('filters', function() {
  beforeEach(function() {
    module('underscore');
    module('gameApp.filters');
  });
  beforeEach(module(function($provide) {
    $provide.factory('serverService', function() {
      var getAvailable = function() {
        return {
          // mock object here
        };
      };
      return {
        getAvailable: getAvailable
      };
    });
  }));
  describe('formatValue', function() {
    it('should format values', inject(function(formatValueFilter) {
      expect(formatValueFilter(1000, 'ABC')).toEqual('å1000');
    }));
  });
});

我在运行测试时遇到的错误是:

TypeError: 'undefined' is not an object (evaluating 'serverService.getAvailable().$promise.then')

您的模拟服务需要返回已解决的承诺。您可以通过注入$q并返回$q.when(data)来执行此操作

但是,我会考虑先重构此过滤器。筛选器旨在快速计算,可能不应依赖于异步调用。我建议将 http 调用移动到控制器,然后将所需的数据传递给过滤器。