2015-01-02 4 views
3

Беря пример кода из 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); 
} 

запустить с помощью кода в угловом обслуживания/завод

var myWorker = new Worker("worker.js"); 

Я хотел бы чтобы иметь возможность тестировать код в worker.js, в идеале работая как часть Угловой службы/фабрики (в отдельном приложении, работающем в веб-работнике?), поэтому я могу использовать систему DI для ввода ложных зависимостей и единичный тестовый код, похожий на тесты для любой другой службы. Как я могу это сделать?

ответ

1

Существует способ сделать это, где основной код, выполняемый веб-рабочим, выполняется как часть отдельного, управляемого вручную модуля Углового модуля.

Для того, чтобы загрузить Угловое в веб-работника

  • Среда должна быть возился с/обезьяны исправленной/взломанный так Угловая не бросать различные исключения, когда он загружает и бутстрап из-за отсутствия window и document объекты
  • Угловая необходимо затем быть включены через 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']); 

Код самого углового модуля может затем быть очень стандарт: с услуг/заводов, определенных по желанию. В этом случае нет необходимости, и я решил поставить простой код примера как обратный вызов 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); 
    }; 
    }); 

})(); 

Это может быть проверена с помощью точно такие же тесты, как если бы это не были предназначены для работы в веб-работника:

// 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.

Смежные вопросы