我有一个 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
的调用以传入更新对象?
最佳答案
我想这有点取决于你如何设置你的规范,我倾向于在每个场景的 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
的模拟版本。
如何实现实际的模拟在一定程度上取决于服务的外观。您似乎正在注册一个回调,所以我只需让模拟在 proxy
属性上有一个方法 on
,然后将其参数(您的回调)存储在一个引用中可从规范中获得。然后您应该能够在需要时简单地调用它。
关于javascript - 如何对在其依赖项上注册回调的 Angular 服务进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24511884/