单元测试AngularFire业力错误

时间:2013-11-25 06:08:24

标签: angularjs unit-testing firebase karma-runner angularfire

当我运行业力单元脚本时,我收到此错误,但我无法弄清楚原因

Error: [$injector:unpr] Unknown provider: FBURLProvider <- FBURL

这是我的指令代码

'use strict';

angular.module('userMenu', ['firebase'])
  .directive('userMenu', function (FBURL, angularFire) {
    return {
      restrict: 'A',
      scope: true ,
      link: function postLink(scope, element, attrs) {

        /**
         * Returns the logged in user information
         * @param {string} FBURL
         * @param {object} scope
         * @returns {promise}
         */
        scope.getUserDataFromFirebase = function(FBURL, scope) {
          var ref = new Firebase(FBURL + '/users/' + scope.auth.id);
          return angularFire(ref, scope, 'user', {})
        }

      }
    };
  });

这是我的规范代码

'use strict';

describe('Directive: userMenu', function () {

  // load the directive's module
  beforeEach(module('userMenu', 'firebase'));

  var element,
    elementScope,
    scope;


  beforeEach(inject(function ($rootScope, $compile, _FBURL_, _angularFire_) {
    scope = $rootScope.$new();
    element = angular.element('<div user-menu></div>');
    element = $compile(element)(scope);
    elementScope = element.scope();
  }));

  it('should get user data', inject(function ($compile) {
    console.log(scope);
  }));
});

老实说,我对单元测试并不熟悉,所以我可能会遗漏一些非常明显的东西,但任何帮助都会受到赞赏。

2 个答案:

答案 0 :(得分:5)

如果您的应用中的所有功能都正常,但您的测试中出现错误,那么您需要在Karma的文件中添加firebase。找到你的karma.conf.js(在yeoman生成的ionic-angular中将此添加到Gruntfile.js的Karma套件中),并使其类似于以下内容:

karma: {
  options: {
    ...
    files: [
      ...
      'https://cdn.firebase.com/v0/firebase.js',
      'app/bower_components/angular-fire/angularFire.js',
      ...
    ],
    ...
  }
  ...
}

然后在您的规范中,包含firebase:

beforeEach(module('Simplift', 'firebase'));

每次您需要使用firebase服务时:

describe/it('some test desc ...', inject(function (..., $firebase) {
  // now we can use $firebase!!
  fireSync = $firebase(new Firebase('https://app_name.firebaseio.com'));
  ...
}));

让我永远想出这个,并希望它能减轻某人的压力。这对我来说现在很有用,但可能不是最干净的方法(请提供建议!),因为你实际上并没有删除firebase数据,但你可以在你的firebase数据库中添加一个“测试”网址。 / p>

答案 1 :(得分:1)

Firbase团队向我指出了Fireseed project中随后被删除的一些测试代码的方向。这是我的单元测试,包括Fireseed项目中的存根

'use strict';

describe('Directive: userMenu', function () {

  // load the directive's module
  beforeEach(module('userMenu', 'firebase', function($provide) {
    $provide.value('Firebase', firebaseStub());
    $provide.value('FBURL', 'FAKE_FB_URL');
    $provide.value('angularFireAuth', angularAuthStub());
  }));


  /**
   * This is from https://github.com/firebase/angularFire-seed/blob/master/test/unit/servicesSpec.js
   */
  function stub() {
    var out = {};
    angular.forEach(arguments, function(m) {
      out[m] = jasmine.createSpy();
    });
    return out;
  }
  /**
   * This is from https://github.com/firebase/angularFire-seed/blob/master/test/unit/servicesSpec.js
   */
  function stub() {
    var out = {};
    angular.forEach(arguments, function(m) {
      out[m] = jasmine.createSpy();
    });
    return out;
  }
  /**
   * This is from https://github.com/firebase/angularFire-seed/blob/master/test/unit/servicesSpec.js
   */
  function reject($q, error) {
    var def = $q.defer();
    def.reject(error);
    return def.promise;
  }
  /**
   * This is from https://github.com/firebase/angularFire-seed/blob/master/test/unit/servicesSpec.js
   */
  function resolve($q, val) {
    var def = $q.defer();
    def.resolve(val);
    return def.promise;
  }
  /**
   * This is from https://github.com/firebase/angularFire-seed/blob/master/test/unit/servicesSpec.js
   */
  function firebaseStub() {
    // firebase is invoked using new Firebase, but we need a static ref
    // to the functions before it is instantiated, so we cheat here by
    // attaching the functions as Firebase.fns, and ignore new (we don't use `this` or `prototype`)
    var fns = stub('set');
    customSpy(fns, 'child', function() { return fns; });

    var Firebase = function() {
      angular.extend(this, fns);
      return fns;
    };
    Firebase.fns = fns;

    return Firebase;
  }
  /**
   * This is from https://github.com/firebase/angularFire-seed/blob/master/test/unit/servicesSpec.js
   */
  function angularAuthStub() {
    var auth = stub('login', 'logout', 'createAccount', 'changePassword');
    auth._authClient = stub('changePassword', 'createUser');
    return auth;
  }
  /**
   * This is from https://github.com/firebase/angularFire-seed/blob/master/test/unit/servicesSpec.js
   */
  function customSpy(obj, m, fn) {
    obj[m] = fn;
    spyOn(obj, m).andCallThrough();
  }

  var element,
    elementScope,
    scope;


  beforeEach(inject(function ($rootScope, $compile) {
    scope = $rootScope.$new();
    element = angular.element('<div user-menu></div>');
    element = $compile(element)(scope);
    elementScope = element.scope();
  }));

  it('should default to a login message', inject(function ($compile) {
    scope.$digest();
    var text = element.text();
    expect(text).toBe('Please login');
  }));

  it('default message should contain a link to login page', inject(function ($compile) {
    scope.$digest();
    var href = element.find('a').attr('href');
    expect(href).toBe('#/login');
  }));
});