Модульное тестирование AngularJS фабрик, которые имеют зависимости
при модульном тестировании угловой фабрики (с Karma + Jasmine), как я могу ввести зависимость заглушки в тестируемую фабрику?
вот:mod = angular.module('myFactoryMod', []);
mod.factory('myFactory', [
'$log', 'oneOfMyOtherServices', function($log, svc) {
return makeSomethingThatDoesSomethingWithTheseDependencies($log, svc);
}
]);
oneOfMyOtherServices
необходимо при создании экземпляра моей фабрики.
вот мой тест:
it('can get an instance of my factory', function() {
var oneOfMyOtherServicesStub;
angular.mock.module('myFactoryMod');
oneOfMyOtherServicesStub = {
someVariable: 1
};
//****How do I get my stub in my target? ****
angular.mock.inject(['myFactory', function(target) {
expect(target).toBeDefined();
}
]);
})
N. B. Я знаю, что $controller
это позволяет для контроллеров, но я не вижу эквивалента для фабрики.
2 ответа:
есть два способа выполнить что-то вроде этого, что я знаю:
- использовать
$provide
и анонимный модуль для введения макета.- введите службу, которую вы хотели бы издеваться и использовать шпионскую способность Жасмин, чтобы обеспечить фиктивные значения.
второй вариант работает только в том случае, если вы точно знаете, какие методы ваш тестируемый код будет вызывать на введенной службе, и вы можете легко издеваться над ними. Как вы, кажется, доступ к данным свойство на службе (а не метод), преследующее первый вариант, может быть лучшим.
используя
$provide
будет примерно выглядеть так:describe('myFactory', function () { // Load your module. beforeEach(module('myFactoryMod')); // Setup the mock service in an anonymous module. beforeEach(module(function ($provide) { $provide.value('oneOfMyOtherServicesStub', { someVariable: 1 }); })); it('can get an instance of my factory', inject(function(myFactory) { expect(myFactory).toBeDefined(); })); });
комментарий @bentsai на самом деле очень полезен для тестирования услуг; для полноты я добавляю пример.
вот тест для
jasmine
который делает примерно то, что вы ищете. Примечание: это требует, чтобы у вас былоangular-mocks
включить (это то, что обеспечивает такие функции, какmodule
иinject
).describe('app: myApp', function() { beforeEach(module('myApp')); var $controller; beforeEach(inject(function(_$controller_) { $controller = _$controller_; })); // Factory of interest is called MyFactory describe('factory: MyFactory', function() { var factory = null; beforeEach(inject(function(MyFactory) { factory = MyFactory; })) it('Should define methods', function() { expect(factory.beAwesome).toBeDefined() expect(factory.beAwesome).toEqual(jasmine.any(Function)) }); }); });
это заглушка для того, что модуль и связанное с ним определение фабрики может выглядеть так:
var app = angular.module('myApp', []); app.factory('MyFactory', function() { var factory = {}; factory.beAwesome = function() { return 'Awesome!'; } return factory; });
в этом случае, понятно использование
inject()
позволяет вам втягивать зависимости, как и следовало ожидать в вашем обычном угловом приложении, и поэтому вы можете создавать требования для поддержки тестирования вещей, которые полагаются на них.