gpt4 book ai didi

javascript - 如何模拟在 AngularJS Jasmine 单元测试中返回 promise 的服务?

转载 作者:IT老高 更新时间:2023-10-28 13:18:28 26 4
gpt4 key购买 nike

我有 myService 使用 myOtherService,它进行远程调用,返回 promise :

angular.module('app.myService', ['app.myOtherService'])
.factory('myService', [
myOtherService,
function(myOtherService) {
function makeRemoteCall() {
return myOtherService.makeRemoteCallReturningPromise();
}

return {
makeRemoteCall: makeRemoteCall
};
}
])

要对 myService 进行单元测试,我需要模拟 myOtherService,使其 makeRemoteCallReturningPromise 方法返回一个 promise 。我就是这样做的:

describe('Testing remote call returning promise', function() {
var myService;
var myOtherServiceMock = {};

beforeEach(module('app.myService'));

// I have to inject mock when calling module(),
// and module() should come before any inject()
beforeEach(module(function ($provide) {
$provide.value('myOtherService', myOtherServiceMock);
}));

// However, in order to properly construct my mock
// I need $q, which can give me a promise
beforeEach(inject(function(_myService_, $q){
myService = _myService_;
myOtherServiceMock = {
makeRemoteCallReturningPromise: function() {
var deferred = $q.defer();

deferred.resolve('Remote call result');

return deferred.promise;
}
};
}

// Here the value of myOtherServiceMock is not
// updated, and it is still {}
it('can do remote call', inject(function() {
myService.makeRemoteCall() // Error: makeRemoteCall() is not defined on {}
.then(function() {
console.log('Success');
});
}));

从上面可以看出,我的 mock 的定义取决于 $q,我必须使用 inject() 加载它。此外,注入(inject)模拟应该发生在 module() 中,它应该在 inject() 之前发生。但是,一旦我更改了模拟的值,它就不会更新。

这样做的正确方法是什么?

最佳答案

我不知道为什么你这样做的方式不起作用,但我通常用 spyOn 函数来做。像这样的:

describe('Testing remote call returning promise', function() {
var myService;

beforeEach(module('app.myService'));

beforeEach(inject( function(_myService_, myOtherService, $q){
myService = _myService_;
spyOn(myOtherService, "makeRemoteCallReturningPromise").and.callFake(function() {
var deferred = $q.defer();
deferred.resolve('Remote call result');
return deferred.promise;
});
}

it('can do remote call', inject(function() {
myService.makeRemoteCall()
.then(function() {
console.log('Success');
});
}));

还请记住,您需要调用 $digest 才能调用 then 函数。请参阅 $q documentation测试 部分.

-----编辑------

仔细查看您的操作后,我认为您的代码中存在问题。在 beforeEach 中,您将 myOtherServiceMock 设置为一个全新的对象。 $provide 永远不会看到这个引用。您只需要更新现有的引用:

beforeEach(inject( function(_myService_, $q){
myService = _myService_;
myOtherServiceMock.makeRemoteCallReturningPromise = function() {
var deferred = $q.defer();
deferred.resolve('Remote call result');
return deferred.promise;
};
}

关于javascript - 如何模拟在 AngularJS Jasmine 单元测试中返回 promise 的服务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23705051/

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