У меня написана служба AngularJS, и я хотел бы ее протестировать.
angular.module('myServiceProvider', ['fooServiceProvider', 'barServiceProvider']).
factory('myService', function ($http, fooService, barService) {
this.something = function() {
// Do something with the injected services
};
return this;
});
В моем файле app.js зарегистрированы:
angular
.module('myApp', ['fooServiceProvider','barServiceProvider','myServiceProvider']
)
Я могу проверить, работает ли DI как таковой:
describe("Using the DI framework", function() {
beforeEach(module('fooServiceProvider'));
beforeEach(module('barServiceProvider'));
beforeEach(module('myServiceProvder'));
var service;
beforeEach(inject(function(fooService, barService, myService) {
service=myService;
}));
it("can be instantiated", function() {
expect(service).not.toBeNull();
});
});
Это доказало, что сервис может быть создан платформой DI, однако затем я хочу провести модульное тестирование службы, что означает имитацию внедренных объектов.
Как мне это сделать?
Я пробовал помещать свои фиктивные объекты в модуль, например
beforeEach(module(mockNavigationService));
и переписав определение службы как:
function MyService(http, fooService, barService) {
this.somthing = function() {
// Do something with the injected services
};
});
angular.module('myServiceProvider', ['fooServiceProvider', 'barServiceProvider']).
factory('myService', function ($http, fooService, barService) { return new MyService($http, fooService, barService); })
Но последнее, похоже, мешает созданию службы DI как все.
Кто-нибудь знает, как я могу имитировать внедренные службы для моих модульных тестов?
Спасибо
Дэвид
javascript
angularjs
mocking
jasmine
angularjs-service
BanksySan
источник
источник
Ответы:
Вы можете внедрить mock-объекты в свой сервис, используя
$provide
.Если у вас есть следующая служба с зависимостью, в которой есть метод getSomething:
Вы можете внедрить фиктивную версию myDependency следующим образом:
Обратите внимание, что из-за обращения к
$provide.value
вам на самом деле нет необходимости явно вводить myDependency где-либо. Это происходит под капотом во время инъекции myService. При настройке здесь mockDependency он также легко может быть шпионом.Спасибо loyalBrown за ссылку на это замечательное видео .
источник
beforeEach(module('myModule'));
звонок ДОЛЖЕН быть передbeforeEach(function () { MOCKING })
звонком, иначе фиктивные данные будут перезаписаны реальными сервисами!$provide
звонки должны быть сделаны перед использованием, в$injector
противном случае вы получите сообщение об ошибке:Injector already created, can not register a module!
Error: [ng:areq] Argument 'fn' is not a function, got Object
, не забудьте поставитьreturn
на линию после$provide.value(...)
. Неявный возврат$provide.value(...)
вызвал для меня эту ошибку.На мой взгляд, не нужно издеваться над самими сервисами. Просто имитируйте функции сервиса. Таким образом, вы можете использовать angular для внедрения ваших реальных сервисов, как это делается во всем приложении. Затем при необходимости смоделируйте функции службы, используя
spyOn
функцию Jasmine .Теперь, если сама служба является функцией, а не объектом, с которым вы можете использовать
spyOn
, есть другой способ сделать это. Мне нужно было это сделать, и я нашел то, что мне очень подходит. Посмотрите, как вы имитируете службу Angular, которая является функцией?источник
Другой способ упростить имитацию зависимостей в Angular и Jasmine - использовать QuickMock. Его можно найти на GitHub, и он позволяет создавать простые макеты для многократного использования. Вы можете клонировать его с GitHub по ссылке ниже. README говорит сам за себя, но надеюсь, что он может помочь другим в будущем.
https://github.com/tennisgent/QuickMock
Он автоматически управляет всем упомянутым выше шаблоном, поэтому вам не нужно записывать весь этот фиктивный код внедрения в каждом тесте. Надеюсь, это поможет.
источник
В дополнение к ответу Джона Галамбоса : если вы просто хотите имитировать определенные методы службы, вы можете сделать это следующим образом:
источник
Если ваш контроллер написан с учетом такой зависимости:
тогда вы можете сделать фальшивку
someDependency
в тесте на жасмин вот так:источник
Недавно я выпустил ngImprovedTesting, который должен упростить имитационное тестирование в AngularJS.
Чтобы протестировать myService (из модуля myApp) с имитацией зависимостей fooService и barService, вы можете просто сделать следующее в своем тесте Jasmine:
Для получения дополнительной информации о ngImprovedTesting ознакомьтесь с его вводным сообщением в блоге: http://blog.jdriven.com/2014/07/ng-improved-testing-mock-testing-for-angularjs-made-easy/
источник
Я знаю, что это старый вопрос, но есть другой более простой способ: вы можете создать макет и отключить оригинал, введенный в одну функцию, это можно сделать, используя spyOn для всех методов. см. код ниже.
источник