我如何单元测试在其依赖项上注册回调的Angular服务?

时间:2014-07-01 13:46:29

标签: javascript angularjs unit-testing signalr jasmine

我有一个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的调用来传递更新对象?

1 个答案:

答案 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中可用的引用中。然后你应该能够在你想要的时候简单地调用它。