Angularjs 如何在Jasmine单元测试中模拟模块API依赖关系?
我有一个案例来单元测试自定义角度指令Angularjs 如何在Jasmine单元测试中模拟模块API依赖关系?,angularjs,unit-testing,dependency-injection,jasmine,Angularjs,Unit Testing,Dependency Injection,Jasmine,我有一个案例来单元测试自定义角度指令myApp,并设置了必要的karma和jasmine配置。 在这个测试用例中,我尝试模拟并存根myApp的依赖模块,它是服务-services.FuzzAPI。 因为我没有访问services.FuzzAPI文件的权限,所以无法使用sinon对其进行模拟 在Angular和Jasmine文档之后,我在.spec文件中设置了spec文件,并遵循以下步骤 首先,在这之前,每个人都根据 并注册myApp模块,以使用angular.mock.module进行测试 然后
myApp
,并设置了必要的karma和jasmine配置。
在这个测试用例中,我尝试模拟并存根myApp
的依赖模块,它是服务-services.FuzzAPI
。
因为我没有访问services.FuzzAPI文件的权限,所以无法使用sinon对其进行模拟
在Angular和Jasmine文档之后,我在.spec
文件中设置了spec文件,并遵循以下步骤
myApp
模块,以使用angular.mock.module
进行测试myApp
指令的$compile步骤的模拟FuzzAPI李>
但是,即使在模拟了依赖关系之后,我仍然得到一个$injector:modulerr
告诉我services.FuzzAPI不可用。
这告诉我soemthing与服务的注册有误。FuzzAPI
依赖项:
LOG LOG: 'before mock'
LOG LOG: 'after mock'
Error: [$injector:modulerr] Failed to instantiate module myApp due to:
Error: [$injector:modulerr] Failed to instantiate module services.FuzzAPI due to:
Error: [$injector:nomod] Module 'services.FuzzAPI' is not available! You either misspelled the module name or forgot to load it
问题:
如何在Jasmine单元测试中模拟指令依赖性
查看代码,我可以看到这个错误在每个(inject(function($rootScope,$compile$injector){
因为在抛出错误之前,injectbeforeach
中的console.log不会被触发
指令和测试规范的要点:
//my-app.js
(function() {
var component = {
id: "myApp",
name: "My App",
templateUrl: localStorage.getItem("baseURL") + "my-app/my-app.html"
};
component.ui = angular.module("myApp", ["services.FuzzAPI"]);
component.ui.directive("myApp", widgetComponent);
function widgetComponent(FuzzAPI) {
// main widget container
function widgetContainer(scope, element, params) {
var api = new FuzzAPI(params);
scope.greeting = "Hello World";
var setGreeting = function(message){
scope.greeting = message;
};
api.onDataEvent("onFuzzEvent", function(data) {
scope.greeting = data;
});
element.on("$destroy", function() {
api.unregister();
scope.$destroy();
});
}
return {
scope: {},
replace: true,
link: widgetContainer,
templateUrl: component.templateUrl
};
}
})();
//my-app.spec.js
describe("myApp", function() {
var $scope, $compile, $provide, $injector, element, fuzzAPIMock, FuzzAPIProvider;
beforeEach(function(){
//mock service FuzzAPI via service provider
fuzzAPIMock = {
greeting : "123",
initializeCurrentItem : function () {
return true;
}
};
console.log("before mock");
//register module and mock dependency
angular.mock.module(function($provide) {
$provide.value('services.FuzzAPI', fuzzAPIMock);
});
angular.mock.module("myApp");
console.log("after mock");
});
beforeEach(inject(function($rootScope, _$compile_, $injector) {
console.log("in inject..");
FuzzAPIProvider = $injector.get('services.FuzzAPI');
$scope = $rootScope.$new(), //create instance of rootScope
$compile = _$compile_;
console.log("in inject before compile..");
element = $compile("<my-app></my-app>")($scope); // compile attaches directives to HTML template
console.log("in inject after compile..");
$scope.$digest(); //loop through DOM watchers, check values and trigger listeners
}));
});
描述(“myApp”,函数(){
var$scope、$compile、$provide、$injector、element、fuzzAPIMock、FuzzAPIProvider;
beforeach(函数(){
//通过服务提供者模拟服务API
fuzzAPIMock={
问候语:“123”,
initializeCurrentItem:函数(){
返回true;
}
};
控制台日志(“模拟前”);
//寄存器模块和模拟依赖项
angular.mock.module(函数($provide){
$provide.value('services.FuzzAPI',fuzzAPIMock);
});
角度模拟模块(“myApp”);
控制台日志(“模拟后”);
});
beforeach(注入(函数($rootScope,$compile,$injector){
console.log(“插入…”);
FuzzAPIProvider=$injector.get('services.FuzzAPI');
$scope=$rootScope.$new(),//创建rootScope的实例
$compile=\$compile;
log(“在编译之前插入…”;
element=$compile(“”($scope);//compile将指令附加到HTML模板
log(“编译后插入…”);
$scope.$digest();//循环DOM监视程序、检查值和触发器侦听器
}));
});
错误:[$injector:nomod]模块“services.FuzzAPI”不可用!您可能拼错了模块名称或忘记加载它
表示应该模拟的是services.FuzzAPI
模块,而不是服务。根据提供的代码,服务名称是FuzzAPI
,应该用构造函数模拟,而不是对象
为了使丢失的模块不会导致错误,应将其存根。可以在顶级description
块中存根一次:
beforeAll(() => {
angular.module('services.FuzzAPI', []);
});
恢复存根模块是不可能的(至少在没有黑客攻击的情况下是不可能的),但如果真正的模块不应该出现在测试中,这并不是一个问题
然后可以像往常一样模拟服务。如果它是FuzzAPI
:,那么应该是
fuzzAPIMock = jasmine.createSpy('').and.returnValue({
greeting : "123",
initializeCurrentItem : jasmine.createSpy('').and.returnValue(true)
});
angular.mock.module(function($provide) {
$provide.value('FuzzAPI', fuzzAPIMock);
});
最好使用Jasmine spies作为模拟/存根函数
错误:[$injector:nomod]模块“services.FuzzAPI”不可用!您可能拼错了模块名称或忘记加载它
表示应该模拟的是services.FuzzAPI
模块,而不是服务。根据提供的代码,服务名称是FuzzAPI
,应该用构造函数模拟,而不是对象
为了使丢失的模块不会导致错误,应将其存根。可以在顶级description
块中存根一次:
beforeAll(() => {
angular.module('services.FuzzAPI', []);
});
恢复存根模块是不可能的(至少在没有黑客攻击的情况下是不可能的),但如果真正的模块不应该出现在测试中,这并不是一个问题
然后可以像往常一样模拟服务。如果它是FuzzAPI
:,那么应该是
fuzzAPIMock = jasmine.createSpy('').and.returnValue({
greeting : "123",
initializeCurrentItem : jasmine.createSpy('').and.returnValue(true)
});
angular.mock.module(function($provide) {
$provide.value('FuzzAPI', fuzzAPIMock);
});
最好使用Jasmine spies作为模拟/存根函数