我试图模拟一个返回promise的服务中存在的函数。
testService.js
describe('Service: ingredientsNames', function () {
var mock = null,
backendReady = null,
namesEndpoint = {execute: function() {}},
ingredientsNames = null,
$rootScope
;
beforeEach(module('aWareAdmin'));
beforeEach(function() {
mock = {
ready: null,
admin: {
ingredients: {
names: function (request) {
return namesEndpoint;
}
}
},
execute: namesEndpoint.execute
};
module(function($provide) {
$provide.value('aWare', mock);
});
inject(function($injector) {
var $q = $injector.get('$q');
$rootScope = $injector.get('$rootScope');
backendReady = $q.defer();
mock.ready = backendReady.promise;
ingredientsNames = $injector.get('ingredientsNames');
});
});
it('should retrieve a list of ingredients names from backend', function() {
backendReady.resolve('ready');
namesEndpoint.execute = function(callback) {
callback({names: []});
};
ingredientsNames.fetch();
$rootScope.$digest();
expect(ingredientsNames.getNames()).toBeDefined();
expect(ingredientsNames.getNames()).toEqual([]);
});
service.js
angular.module('aWareAdmin')
.service('ingredientsNames', [
'aWare',
'$q',
'$log',
'env',
function(
aware,
$q,
$log,
env
) {
var names = [],
msg = {
cursor: null,
size: 100
},
requestSent = false,
hasMore = true,
self = this,
defaultLanguage = {
code: 'nc',
name: 'Default (INCI)'
}
;
// Recursive function for getting ingredients names
this.fetch = function() {
var deferred = $q.defer();
if (requestSent) {
return deferred.promise;
}
if (!hasMore) {
deferred.resolve(names);
return deferred.promise;
}
if (!env.isProduction()) {
msg.size = 20;
}
aware.execute('admin.ingredients.names', msg).then(function(response) {
if (response.names) {
$log.info('Received Ingredients Names: ', response.names);
angular.forEach(response.names, function(name) {
this.push(name);
}, names);
msg.cursor = response.cursor;
hasMore = response.more;
deferred.resolve(response.names);
} else {
$log.debug('Ingredients Names API not sending names: ', response);
hasMore = response.more;
deferred.reject('No items were received.');
}
requestSent = false;
if (hasMore && env.isProduction()) {
self.fetch();
}
}, function (error) {
$log.debug('Error: fetch ingredients names!', error);
});
requestSent = true;
return deferred.promise;
};
// Return ingredients names
this.getNames = function() {
return names;
};
它会抛出错误,
PhantomJS 2.1.1 (Linux 0.0.0) Service: ingredientsNames should return the cached list of ingredients names and retrieve more FAILED
TypeError: undefined is not a function (evaluating 'mock.callback({names: []})') in test/spec/services/ingredientsnames.js (line 218)
execute@test/spec/services/ingredientsnames.js:218:26
fetch@app/scripts/services/ingredientsnames.js:54:22
test/spec/services/ingredientsnames.js:239:31
PhantomJS 2.1.1 (Linux 0.0.0): Executed 127 of 168 (34 FAILED) (0 secs / 22.615 sePhantomJS 2.1.1 (Linux 0.0.0): Executed 128 of 168 (34 FAILED) (0 secs / 22.618 sePhantomJS 2.1.1 (Linux 0.0.0): Executed 129 of 168 (34 FAILED) (0 secs / 22.621 sePhantomJS 2.1.1 (Linux 0.0.0): Executed 130 of 168 (34 FAILED) (0 secs / 22.626 sePhantomJS 2.1.1 (Linux 0.0.0) Service: ingredientsNames #remove should remove identifiers of the given ingredient FAILED
TypeError: admin.ingredients.names is not a function (evaluating 'callback({names: namesList[0], cursor: 'c1'})') in test/spec/services/ingredientsnames.js (line 236)
execute@test/spec/services/ingredientsnames.js:236:21
fetch@app/scripts/services/ingredientsnames.js:54:22
test/spec/services/ingredientsnames.js:317:35
我实际上想要模拟aware.execute
函数,该函数必须在调用{{1}时返回names
(由namesEndpoint.execute
设置的) }