当我运行业力单元脚本时,我收到此错误,但我无法弄清楚原因
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);
}));
});
老实说,我对单元测试并不熟悉,所以我可能会遗漏一些非常明显的东西,但任何帮助都会受到赞赏。
答案 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');
}));
});