【发布时间】:2015-07-21 07:19:09
【问题描述】:
我试图在 Angular 的 jasmine 测试中模拟原生 WebSocket,我可以监视构造函数和 send 函数,但我不知道如何欺骗 onmessage 的调用。
WebSocket 被提取为一个 Angular 常量:webSocket。
我的测试如下所示:
describe('Data Service', function () {
var dataService,
$interval,
ws;
beforeEach(function () {
module('core', function ($provide) {
ws = jasmine.createSpy('constructor');
ws.receiveMessage = function (message) {
this.onmessage(message);
};
$provide.constant('webSocket', ws);
});
inject(function (_dataService_, _$interval_) {
dataService = _dataService_;
$interval = _$interval_;
});
});
it("should call subscribers when a message is received", function () {
var callback = jasmine.createSpy('onMessage callback');
function message(type) {
return {
data: {
type: type,
data: 'data'
}
};
}
// Subscribe to messages via the exposed function.
// Subscribe to one of them twice to test that all subscribers are called and not just the first one.
dataService.onMessage(21, callback);
dataService.onMessage(21, callback);
dataService.onMessage(22, callback);
dataService.onMessage(23, callback);
// Pick 3 numbers that are valid data types to test.
ws.receiveMessage(message(21));
ws.receiveMessage(message(22));
ws.receiveMessage(message(23));
expect(callback.calls.count()).toBe(4);
expect(callback.calls.allArgs()).toBe([message(21).data, message(21).data, message(22).data, message(23).data]);
});
});
我的代码如下所示:
angular.module('core', []).constant('webSocket', WebSocket);
angular.module('core').factory('dataService', function ($interval, webSocket) {
function openSocket() {
sock = new webSocket('ws://localhost:9988');
sock.onmessage = function (message) {
var json = JSON.parse(message.data);
onMessageSubscribers[json.type].forEach(function (sub) {
sub(json);
});
};
}
function onMessage(type, func) {
onMessageSubscribers[type].push(func);
}
openSocket();
return {
onMessage: onMessage
};
});
onMessageSubscribers 是一个已定义的数组,其中包含正确的类型(int 键),但它与问题无关。
我收到以下错误:
TypeError: 'undefined' is not a function(评估 'this.onmessage(message)')
onmessage 似乎是由测试前运行的角度代码定义的,但我想知道这是否与构造对象与 JS 中的常规对象有何不同有关,我真的没有任何与他们的经验。
我尝试了几种不同的方法来做到这一点,比如打电话给ws.prototype.onmessage 或只是ws.onmessage。
如果我在dataService 中的适当位置放置一个console.log(sock.onmessage);,并在我在测试中调用onmessage 之前放置另一个日志:
函数(消息){ ... }
未定义
如何强制调用 onmessage 或任何其他 WebSocket 事件?
【问题讨论】:
标签: javascript angularjs unit-testing mocking jasmine