gpt4 book ai didi

javascript - 如何使用 Jasmine 测试 AngularJS Controller 返回的 Promise 值?

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:07:56 26 4
gpt4 key购买 nike

我有一个 Controller 公开了一个函数,该函数在 rest 调用后返回一些文本。它工作正常,但我无法使用 Jasmine 对其进行测试。 测试中 promise 处理程序中的代码永远不会执行

Controller :

/* 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
})
});
});

最佳答案

除非调用 promise 回调,否则 then 中的任何内容都不会运行 - 这有误报的风险,就像您在这里遇到的那样。 测试将在这里通过,因为 expect 从未运行过。

有很多方法可以确保您不会得到这样的误报。示例:

A) 返回 promise

Jasmine 会等待 promise 在超时时间内解决。

  • 如不及时解决,测试将失败。
  • 如果 promise 被拒绝,测试也会失败。

注意如果您忘记返回,您的测试会给出误报!

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 没有在超时时间内调用,测试将失败。
  • 如果使用参数调用done,测试将失败。
    这里的 catch 会将错误传递给 jasmine,你会看到错误在输出中。

当心如果您忘记了 catch,您的错误将被吞没并且您的测试将因一般超时错误而失败。

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) 使用 spy 和手摇曲柄(同步测试)

如果您不完美,这可能是编写测试的最安全方式。

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、超时和范围更改,以使 Controller /服务更进一步$httpBackend.flush()$timeout.flush()scope.$apply()

关于javascript - 如何使用 Jasmine 测试 AngularJS Controller 返回的 Promise 值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26319873/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com