我一直在尝试模拟量角器中的一些服务,在查看了一些博客之后,我找到了一个适合我的解决方案。这个想法不是做大量的模拟,只是产生一些错误响应;因为对于装置,我的 API 服务器中已经有一个后门来填充后端。
此解决方案使用$provide.decorator()
来更改某些方法。以下是它在测试中的使用方式:
it('should mock a service', function () {
app.mock.decorateService({
// This will return a rejected promise when calling to "user"
// service "login()" method resolved with the given object.
// rejectPromise() is a convenience method
user: app.mock.rejectPromise('login', { type: 'MockError' }),
// You can decorate the service
// Warning! This code get's stringified and send to the browser
// it does not have access to node
api: function ($delegate, $q) {
$delegate.get = function () {
var deferred = $q.defer();
deferred.resolve({ id: 'whatever', name: 'tess' });
return defer.promise;
};
return $delegate;
},
// Internally decorateService converts the function to string
// so if you prefer you can set an string. Usefull for creating your
// own helper methods like "rejectPromise()".
dialog: [
"function ($delegate, $window) {",
"$delegate.alert = $window.alert;",
"return $delegate;",
"}"
].join('\n')
});
// ...
// Important!
app.mock.clearDecorators();
});
这里的代码:
App.prototype.mock = {
// This must be called before ".get()"
decorateService: function (services) {
var code = [
'var decorer = angular.module("serviceDecorator", ["visitaste"]);',
'decorer.config(function ($provide) {'
];
for (var service in services) {
var fn = services[service];
if (_.isFunction(fn)) {
code.push('$provide.decorator("'+ service +'", '+ String(fn) +');');
} else if (_.isString(fn)) {
code.push('$provide.decorator("'+ service +'", '+ fn +');');
}
}
code.push('});');
browser.addMockModule('serviceDecorator', code.join('\n'));
},
clearDecorators: function () {
browser.clearMockModules();
},
rejectPromise: function (method, error, delay) {
return [
'function ($delegate, $q) {',
'$delegate.'+ method +' = function () {',
'var deferred = $q.defer();',
'',
'setTimeout(function () {',
'deferred.reject('+ JSON.stringify(error) +');',
'}, '+ (delay || 200) +');',
'',
'return deferred.promise;',
'};',
'',
'return $delegate;',
'}'
].join('\n');
}
};