AngularJS Karma 测试规范 Promise 未解决且未调用 .then()
AngularJS Karma Test Spec Promise not resolved and .then() not called
我在 AngularJS Karma 单元测试服务时遇到问题。
我有一个服务方法是这样的:
service.getIntersectingElements = function (element, elements) {
var deferred = $q.defer();
var tolerance = 20;
var intersectingElements = [];
$timeout(function () {
for (var i = 0; i < elements.length; i++) {
if (element.$$hashKey != elements[i].$$hashKey)
if (service.checkIntersection(element.Location, elements[i].Location, tolerance))
intersectingElements.push(elements[i]);
}
if (intersectingElements.length > 0)
deferred.resolve(intersectingElements);
else
deferred.reject();
});
return deferred.promise;
};
控制器调用它就可以正常工作。但我想测试那个方法,returns 稍后解决了一个承诺。我想得到值解析并在单元测试中比较它。
所以我写了下面的业力测试:
it('should get the intersecting elements', function () {
var element = {Id: 1, Name: 'Water', Location: {x: 200, y: 200}};
var elements = [{Id: 2, Name: 'Fire', Location: {x: 200, y: 200}}];
service.getIntersectingElements(element, elements).then(function (result) {
expect(result).toEqual([{Id: 2, Name: 'Fire', Location: {x: 200, y: 200}}]);
});
});
我调用服务方法与在控制器中完全相同。但是测试以完成结束,没关系。但是如果我改变行
expect(result).toEqual([{Id: 2, Name: 'Fire', Location: {x: 200, y: 200}}]);
至
expect(result).toEqual("Test");
测试也完成了,没有失败。但在那种情况下,我预计测试会失败。
我已经尝试在服务方法调用后注入 $rootScope
并调用 $rootScope.$digest();
。这应该解决了之前的承诺,但实际上它没有任何效果,如果我放置摘要或不...
所以我的问题是,如何在 karma 单元测试中测试 service 方法返回的 promise 并比较已解析并传递给 promise 的 then() 的值。
编辑:
我在服务方法调用后尝试了 $timeout.flush();
和 $rootScope.$digest();
。
如果有帮助,我注入了这样的服务:
var service;
var $timeout;
var $rootScope;
beforeEach(module('app'));
beforeEach(module('app.services'));
beforeEach(angular.mock.inject(function (intersectService, _$timeout_, _$rootScope_) {
service = intersectService;
$timeout = _$timeout_;
$rootScope = _$rootScope_;
}));
好的,我自己修好了...
首先...我需要刷新超时(我之前尝试过)并且我需要应用范围
it('should get the intersecting elements', function () {
var element = {Id: 1, Name: 'Water', Location: {x: 200, y: 200}, $$hashKey: "1"};
var elements = [
{Id: 1, Name: 'Water', Location: {x: 200, y: 200}, $$hashKey: "1"},
{Id: 2, Name: 'Fire', Location: {x: 200, y: 200}, $$hashKey: "2"}
];
var promise = service.getIntersectingElements(element, elements);
var result;
promise.then(function (res) {
result = res;
},
function (error) {
result = "error";
});
$rootScope.$apply();
$timeout.flush();
expect(result).toEqual([{Id: 2, Name: 'Fire', Location: {x: 250, y: 200}, $$hashKey: "2"}]);
});
整个事情现在看起来像上面那样。
但是其次……那不是真正的错误。我在我的服务方法中使用了 $$hashKey
属性 (参见上面的问题),(显然)没有设置,因为我没有在我的测试数据中设置它。如果变量在 $scope
上,通常 $$hashKey
存在。所以没记得设置。
所以答案是设置 $$hashKey
,如上面的代码所示。
如果您使用 angular.equals,则不需要 $$hashKey,因为它会忽略 $* 属性(和函数)。
expect(angular.equals(result, [{Id: 2, Name: 'Fire', Location: {x: 250, y: 200}}])).toBe(true);
我将此添加为答案,因为我没有足够的代表来 post 发表评论。
我在 AngularJS Karma 单元测试服务时遇到问题。
我有一个服务方法是这样的:
service.getIntersectingElements = function (element, elements) {
var deferred = $q.defer();
var tolerance = 20;
var intersectingElements = [];
$timeout(function () {
for (var i = 0; i < elements.length; i++) {
if (element.$$hashKey != elements[i].$$hashKey)
if (service.checkIntersection(element.Location, elements[i].Location, tolerance))
intersectingElements.push(elements[i]);
}
if (intersectingElements.length > 0)
deferred.resolve(intersectingElements);
else
deferred.reject();
});
return deferred.promise;
};
控制器调用它就可以正常工作。但我想测试那个方法,returns 稍后解决了一个承诺。我想得到值解析并在单元测试中比较它。
所以我写了下面的业力测试:
it('should get the intersecting elements', function () {
var element = {Id: 1, Name: 'Water', Location: {x: 200, y: 200}};
var elements = [{Id: 2, Name: 'Fire', Location: {x: 200, y: 200}}];
service.getIntersectingElements(element, elements).then(function (result) {
expect(result).toEqual([{Id: 2, Name: 'Fire', Location: {x: 200, y: 200}}]);
});
});
我调用服务方法与在控制器中完全相同。但是测试以完成结束,没关系。但是如果我改变行
expect(result).toEqual([{Id: 2, Name: 'Fire', Location: {x: 200, y: 200}}]);
至
expect(result).toEqual("Test");
测试也完成了,没有失败。但在那种情况下,我预计测试会失败。
我已经尝试在服务方法调用后注入 $rootScope
并调用 $rootScope.$digest();
。这应该解决了之前的承诺,但实际上它没有任何效果,如果我放置摘要或不...
所以我的问题是,如何在 karma 单元测试中测试 service 方法返回的 promise 并比较已解析并传递给 promise 的 then() 的值。
编辑:
我在服务方法调用后尝试了 $timeout.flush();
和 $rootScope.$digest();
。
如果有帮助,我注入了这样的服务:
var service;
var $timeout;
var $rootScope;
beforeEach(module('app'));
beforeEach(module('app.services'));
beforeEach(angular.mock.inject(function (intersectService, _$timeout_, _$rootScope_) {
service = intersectService;
$timeout = _$timeout_;
$rootScope = _$rootScope_;
}));
好的,我自己修好了...
首先...我需要刷新超时(我之前尝试过)并且我需要应用范围
it('should get the intersecting elements', function () {
var element = {Id: 1, Name: 'Water', Location: {x: 200, y: 200}, $$hashKey: "1"};
var elements = [
{Id: 1, Name: 'Water', Location: {x: 200, y: 200}, $$hashKey: "1"},
{Id: 2, Name: 'Fire', Location: {x: 200, y: 200}, $$hashKey: "2"}
];
var promise = service.getIntersectingElements(element, elements);
var result;
promise.then(function (res) {
result = res;
},
function (error) {
result = "error";
});
$rootScope.$apply();
$timeout.flush();
expect(result).toEqual([{Id: 2, Name: 'Fire', Location: {x: 250, y: 200}, $$hashKey: "2"}]);
});
整个事情现在看起来像上面那样。
但是其次……那不是真正的错误。我在我的服务方法中使用了 $$hashKey
属性 (参见上面的问题),(显然)没有设置,因为我没有在我的测试数据中设置它。如果变量在 $scope
上,通常 $$hashKey
存在。所以没记得设置。
所以答案是设置 $$hashKey
,如上面的代码所示。
如果您使用 angular.equals,则不需要 $$hashKey,因为它会忽略 $* 属性(和函数)。
expect(angular.equals(result, [{Id: 2, Name: 'Fire', Location: {x: 250, y: 200}}])).toBe(true);
我将此添加为答案,因为我没有足够的代表来 post 发表评论。