我有一个AngularJs服务,它依赖于SignalR客户端进行基于推送的更新。
MyService
向SignalR代理注册一个函数来处理更新,当SignalR服务器调用客户端方法receiveUpdate
时调用该更新,如下所示:
app.factory('MyService', function ($rootScope, signalRClient) {
signalRClient.proxy.on('receiveUpdate', function (update) {
$rootScope.$apply(function () {
handleUpdate(update);
});
});
function handleUpdate(update) {
// ....
}
return {
getUpdates: function () {
// ....
}
}
});
如何模仿signalRClient
以便我可以隔离MyService
中的逻辑?如何伪造对receiveUpdate
的调用来传递更新对象?
答案 0 :(得分:1)
我想这取决于你如何设置你的规范,我倾向于为每个场景加载beforeEach
中的任何模块,并且会这样做。
var myMock;
var receiveUpdate;
beforeEach(module('whateverModuleSignalRClientIsIn', function($provide) {
myMock = {
proxy: {
on: function(id, callback) {
receiveUpdate = callback;
}
}
};
$provide.value('signalRClient', myMock);
}));
beforeEach(module('whateverModuleMyServiceIsIn'));
beforeEach(inject(function(MyService) {
// MyService will not be instantiated untill it has been injected
// and at this point signalRClient has been replaced with the mock already
}));
it('receives updates', function() {
//This should trigger the callback in your service
receiveUpdate({});
});
这将确保您的服务模块加载了myService
的模拟版本。
如何实现实际的模拟取决于服务的外观。你似乎正在注册一个回调,所以我只是让mock在on
属性上有一个方法proxy
,然后将它的参数(你的回调)存储在specs中可用的引用中。然后你应该能够在你想要的时候简单地调用它。