web worker的单元测试代码
Unit test code of web worker
以 https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/basic_usage 中的示例代码为例,以下内容由网络工作者运行
// in worker.js
onmessage = function(e) {
console.log('Message received from main script');
var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
console.log('Posting message back to main script');
postMessage(workerResult);
}
通过 Angular service/factory
中的代码运行
var myWorker = new Worker("worker.js");
我希望能够对 worker.js
中的代码进行单元测试,最好将其作为 Angular service/factory 的一部分运行(在 Web Worker 中运行的单独应用程序中?),因此我可以使用 DI 系统注入依赖项的模拟,并使单元测试代码看起来很像任何其他服务的测试。我该怎么做?
有一种方法可以做到这一点,网络工作者中的主要代码 运行 是 运行 作为单独的、手动引导的 Angular 模块的一部分。
为了在 web worker 中加载 Angular
- 环境需要修补 with/monkey patched/hacked 所以 Angular 不会在加载和引导时由于缺少
window
和 [=14 而抛出各种异常=] 对象
- Angular 必须通过
importScripts
包含
- 那么您想要 运行 的模块必须通过
importScripts
包含
- 然后手动引导模块。
执行此操作的示例代码:
// worker.js
// Angular needs a global window object
var window = self;
// Skeleton properties to get Angular to load and bootstrap.
self.history = {};
var document = {
readyState: 'complete',
querySelector: function() {},
createElement: function() {
return {
pathname: '',
setAttribute: function() {}
}
}
};
// Load Angular: must be on same domain as this script
importScripts('angular.js');
// Put angular on global scope
angular = window.angular;
// Standard angular module definition
importScripts('worker-app.js');
// No root element seems to work fine
angular.bootstrap(null, ['worker-app']);
Angular 模块本身的代码可以非常标准:根据需要定义 services/factories 。在这种情况下,需要 none,我选择将示例的简单代码作为 run
回调(我从问题中省略了 console.log
)。
// worker-app.js
(function() {
'use strict';
var app = angular.module('worker-app', []);
app.run(function($window) {
$window.onmessage = function(e) {
var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
$window.postMessage(workerResult);
};
});
})();
然后可以使用完全相同的测试来测试它,就好像它不打算 运行 在 web worker 中一样:
// worker-app-spec.js
describe('worker-app', function() {
'use strict';
var $window;
beforeEach(module('worker-app'));
beforeEach(inject(function(_$window_) {
$window = _$window_;
}));
beforeEach(function() {
spyOn($window, 'postMessage');
})
it('attaches to $window onmessage', function() {
var data = [2,3];
var result = 'Result: ' + (data[0] * data[1]);
$window.onmessage({data: data});
expect($window.postMessage).toHaveBeenCalledWith(result);
});
});
我不太喜欢破解环境来加载 Angular,因为我觉得它很脆弱,所以非常欢迎其他答案!上面的代码是使用 AngularJS v1.3.7.
测试的
以 https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/basic_usage 中的示例代码为例,以下内容由网络工作者运行
// in worker.js
onmessage = function(e) {
console.log('Message received from main script');
var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
console.log('Posting message back to main script');
postMessage(workerResult);
}
通过 Angular service/factory
中的代码运行var myWorker = new Worker("worker.js");
我希望能够对 worker.js
中的代码进行单元测试,最好将其作为 Angular service/factory 的一部分运行(在 Web Worker 中运行的单独应用程序中?),因此我可以使用 DI 系统注入依赖项的模拟,并使单元测试代码看起来很像任何其他服务的测试。我该怎么做?
有一种方法可以做到这一点,网络工作者中的主要代码 运行 是 运行 作为单独的、手动引导的 Angular 模块的一部分。
为了在 web worker 中加载 Angular
- 环境需要修补 with/monkey patched/hacked 所以 Angular 不会在加载和引导时由于缺少
window
和 [=14 而抛出各种异常=] 对象 - Angular 必须通过
importScripts
包含
- 那么您想要 运行 的模块必须通过
importScripts
包含
- 然后手动引导模块。
执行此操作的示例代码:
// worker.js
// Angular needs a global window object
var window = self;
// Skeleton properties to get Angular to load and bootstrap.
self.history = {};
var document = {
readyState: 'complete',
querySelector: function() {},
createElement: function() {
return {
pathname: '',
setAttribute: function() {}
}
}
};
// Load Angular: must be on same domain as this script
importScripts('angular.js');
// Put angular on global scope
angular = window.angular;
// Standard angular module definition
importScripts('worker-app.js');
// No root element seems to work fine
angular.bootstrap(null, ['worker-app']);
Angular 模块本身的代码可以非常标准:根据需要定义 services/factories 。在这种情况下,需要 none,我选择将示例的简单代码作为 run
回调(我从问题中省略了 console.log
)。
// worker-app.js
(function() {
'use strict';
var app = angular.module('worker-app', []);
app.run(function($window) {
$window.onmessage = function(e) {
var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
$window.postMessage(workerResult);
};
});
})();
然后可以使用完全相同的测试来测试它,就好像它不打算 运行 在 web worker 中一样:
// worker-app-spec.js
describe('worker-app', function() {
'use strict';
var $window;
beforeEach(module('worker-app'));
beforeEach(inject(function(_$window_) {
$window = _$window_;
}));
beforeEach(function() {
spyOn($window, 'postMessage');
})
it('attaches to $window onmessage', function() {
var data = [2,3];
var result = 'Result: ' + (data[0] * data[1]);
$window.onmessage({data: data});
expect($window.postMessage).toHaveBeenCalledWith(result);
});
});
我不太喜欢破解环境来加载 Angular,因为我觉得它很脆弱,所以非常欢迎其他答案!上面的代码是使用 AngularJS v1.3.7.
测试的