Angularjs 控制器函数上的类型错误`
我正在我的控制器上运行一个测试,以确定它是否正确定义,但我在控制器对象上不断得到一个Angularjs 控制器函数上的类型错误`,angularjs,jasmine,Angularjs,Jasmine,我正在我的控制器上运行一个测试,以确定它是否正确定义,但我在控制器对象上不断得到一个TypeError:undefined。下面是完整的错误: Search Controller should have the controller defined <<< FAILURE! * TypeError: 'undefined' is not an object (evaluating 'myMenuDataLoad.then') * Expected undefined to
TypeError:undefined
。下面是完整的错误:
Search Controller
should have the controller defined <<< FAILURE!
* TypeError: 'undefined' is not an object (evaluating 'myMenuDataLoad.then')
* Expected undefined to be defined.
我通过在参数中传递控制器所需的一切来初始化控制器,即scope
、headerService
、menuService
和navigationService
——我使用jasmine.createSpyObj
方法模拟这些服务,并传入所有相关方法(控制器上使用的方法):
控制器的实际初始化发生在这里:
beforeEach(inject(function($rootScope, $injector, $controller, _headerService_, _menuService_, _navigationService_) {
scope = $rootScope.$new();
// Instantiate the controller
searchController = $controller('VisibilitySearchController', {
$scope : scope,
headerService : headerService,
menuService : menuService,
navigationService : navigationService
});
}));
那么我做错了什么?为什么考试(见下文)没有通过
it("should have the controller defined", function() {
expect(searchController).toBeDefined();
});
我是否正确地模拟了服务?为了正确初始化局部控制器变量及其使用的方法,需要对其执行哪些操作
谢谢
更新 我已经对此进行了进一步的研究,但不幸的是仍然收到相同的未定义错误。当您创建一个服务的模拟对象时,您是否必须为该服务提供您所使用的所有依赖项和方法?例如:
menuService = jasmine.createSpyObj('menuService', ['$parse','$q', 'dataService', 'loadData', 'then']);
module(function($provide) {
$provide.value('menuService', menuService);
});
在这里,当我创建模拟对象时,我为它提供了它所期望的所有依赖项,另外我添加了两个函数,我在控制器中使用了这两个函数。
那么,如何在模拟对象中模拟函数呢?我尝试了这个,但仍然得到相同的错误:
menuService.loadData = jasmine.createSpy( 'loadData()' ).andReturn( data );
如注释中所述,您的
menuService.loadData()
将始终返回未定义的,因此计算表达式myMenuDataLoad。然后,
将始终失败,如错误中所述。您必须做的是提供一个menuService.loadData
的实现,它将返回一个承诺。如果您希望调用这些方法,但不依赖它的任何返回值,那么您可以按照您的方式进行模拟。如果需要该方法返回某些内容,可以通过以下方式定义menuService
:
var menuService = {
loadData: function() {
var deferred = $q.defer();
var data = []; //put any data you need here to be returned within the promise
deferred.resolve{data);
return deferred.promise;
}
}
module(function($provide) {
$provide.value('menuService', menuService);
});
spyOn(menuService, "loadData").andCallThrough()
您将需要$q
的实例,您可以在inject
调用中获得该实例,类似于$rootScope
,$injector
等
如果您想监视menuService.load
函数,可以这样做:
var menuService = {
loadData: function() {
var deferred = $q.defer();
var data = []; //put any data you need here to be returned within the promise
deferred.resolve{data);
return deferred.promise;
}
}
module(function($provide) {
$provide.value('menuService', menuService);
});
spyOn(menuService, "loadData").andCallThrough()
这将保持方法的模拟实现,但仍然允许您断言它已被调用等。我认为您不需要它。在测试中,
menuService.loadData()
始终返回未定义,因此myMenuDataLoad。然后,
语句将失败,因为myMenuDataLoad
将未定义。你必须模仿menuService.loadData(),以返回一个承诺,该承诺将解析为一个适当的数据结果。你能通过提供一个例子来详细说明吗?谢谢你的例子,它现在让事情变得更清楚了