javascript – 如何使用Jasmine测试AngularJS控制器在Promise中返回的值?
作者:互联网
我有一个控制器,它暴露了一个在休息调用后返回一些文本的函数.它工作正常,但我无法使用Jasmine进行测试.测试中的promise处理程序内的代码永远不会执行.
控制器:
/* global Q */
'use strict';
angular.module('myModule', ['some.service'])
.controller('MyCtrl', ['$scope', 'SomeSvc', function ($scope, SomeSvc) {
$scope.getTheData = function (id) {
var deferred = Q.defer();
var processedResult = '';
SomeSvc.getData(id)
.then(function (result) {
//process data
processedResult = 'some stuff';
deferred.resolve(processedResult);
})
.fail(function (err) {
deferred.reject(err);
});
return deferred.promise;
}
}]);
考试:
describe('some tests', function() {
var $scope;
var $controller;
var $httpBackend;
beforeEach(function() {
module('myModule');
inject(function(_$rootScope_, _$controller_, _$httpBackend_) {
$scope = _$rootScope_.$new();
$controller = _$controller_;
$httpBackend = _$httpBackend_;
//mock the call that the SomeSvc call from the controller will make
$httpBackend.expect('GET', 'the/url/to/my/data');
$httpBackend.whenGET('the/url/to/my/data')
.respond({data:'lots of data'});
$controller ('MyCtrl', {
$scope: $scope
});
});
});
describe('test the returned value from the promise', function() {
var prom = $scope.getTheData(someId);
prom.then(function(result) {
expect(result).toBe('something expected'); //this code never runs
})
});
});
解决方法:
除非调用承诺回调,否则任何内部的任何内容都不会被运行 – 这就像你在这里遇到的假阳性风险一样.由于期望从未运行,测试将通过此处.
有很多方法可以确保你不会像这样得到误报.例子:
A)回报承诺
Jasmine将等待在超时内解决的承诺.
>如果未及时解决,测试将失败.
>如果承诺被拒绝,测试也将失败.
当心如果您忘记了回报,您的测试将给出误报!
describe('test the returned value from the promise', function() {
return $scope.getTheData(someId)
.then(function(result) {
expect(result).toBe('something expected');
});
});
B)使用Jasmine提供的完成回调测试方法
>如果在超时内未调用done,则测试将失败.
>如果使用参数调用done,则测试将失败.
这里的catch会将错误传递给jasmine,你会看到错误
在输出中.
注意如果您忘记了捕获,则会吞下您的错误并且您的测试将因通用超时错误而失败.
describe('test the returned value from the promise', function(done) {
$scope.getTheData(someId)
.then(function(result) {
expect(result).toBe('something expected');
done();
})
.catch(done);
});
C)使用间谍和手摇(同步测试)
如果你不完美,这可能是最安全的编写测试方法.
it('test the returned value from the promise', function() {
var
data = { data: 'lots of data' },
successSpy = jasmine.createSpy('success'),
failureSpy = jasmine.createSpy('failure');
$scope.getTheData(someId).then(successSpy, failureSpy);
$httpBackend.expect('GET', 'the/url/to/my/data').respond(200, data);
$httpBackend.flush();
expect(successSpy).toHaveBeenCalledWith(data);
expect(failureSpy).not.toHaveBeenCalled();
});
同步测试技巧
您可以在需要时手动启动httpBackend,超时和更改范围,以使控制器/服务更进一步. $httpBackend.flush(),$timeout.flush(),scope.$apply().
标签:javascript,angularjs,promise,jasmine,q 来源: https://codeday.me/bug/20190717/1490396.html