В угловом углу все, кажется, есть крутая кривая обучения. Устройство тестирования углового приложения определенно не избежит этой парадигмы.
Когда я впервые начал с TDD и Angular, я чувствовал, что я провожу дважды (может быть, больше) столько времени на выяснение, как правильно, как правильно проверить, и, возможно, еще больше настроить мои тесты. Но как Бен Надель Положите его в свой блог, есть взлеты и падения в угловом процессе обучения – его график (ниже) определенно мой опыт с угловой.
Источник: Бен Надель
Однако, как я прогрессировал больше о том, чтобы узнать больше о угловых и монтажных тестировании, я провожу гораздо меньше времени на создание тестов и гораздо больше времени на создание тестов, идущих от красного до зеленого цвета – это хорошее чувство.
Я столкнулся с разными способами создания монтажного теста на услуги и обещаниям. Так что на код! Я уверен, что ты не хочешь слушать какого-то парень-блаб о его любви … Достижения – обучение рамки.
Вот как я начал издеваться над моими службами и обещаниями. Я буду использовать контроллер, но услуги и обещания могут быть издеваться в других местах, используя ту же технику.
describe('Controller: Products', function () { var//iable declarations $scope, $rootScope, ProductsMock = { getProducts: function () { } // There might be other methods as well but I'll stick to one for the sake of conciseness }, PRODUCTS = [{},{},{}] ; beforeEach(function () { module('App.Controllers.Products'); }); beforeEach(inject(function ($controller, _$rootScope_) { //Set up our mocked promise var promise = { then: jasmine.createSpy() }; //Set up our scope $rootScope = _$rootScope_; $scope = $rootScope.$new(); //Set up our spies spyOn(ProductsMock, 'getProducts').andReturn(promise); //Initialize the controller $controller('ProductsController', { $scope: $scope, Products: ProductsMock }); //Resolve the promise promise.then.mostRecentCall.args[0](PRODUCTS); })); describe('Controller Initialization', function () { it('should have a populated array of products', function () { expect('ProductsMock.getProducts').toHaveBeenCalled(); }); }); });
Это сработало, но со временем я думал там Должен быть лучшим способом. Для одного я ненавидел
promise.then.mostRecentCall
вещь, и если я хотел поинвизировать контроллер, я должен был вытащить его из Rebedeach
Блок и введите его индивидуально в каждый тест, делая наши тесты не высохнуть.
Там должен быть лучший способ…
Затем я наткнулся на несколько других записей, блоги и примеры стойки (вы называете его, я, наверное, там), и я видел использование библиотеки $ q.
Ох!
Зачем создавать целое издевание обещания, когда мы можем просто использовать инструмент, который угла дает нам. Наш код выглядит уборщиком, и это гораздо более интуитивно понятно.
- нет уродливых
Обещание. Затем.mostrecent
вещь. Затем высушите все, оберните создание контроллера в функции, поэтому мы можем иметь больше контроля над тем, как контроллер ведет себя для настройки наших различных условий испытаний благодаря использованию параметров и констант. Теперь мы получаем где-то.
Далее в итерации тестирования подразделения было это:
describe('Controller: Products', function () { var//iable declarations $scope, $rootScope, $q, $controller, products, PROMISE = { resolve: true, reject: false }, PRODUCTS = [{},{},{}] //constant for the products that are returned by the service ; beforeEach(function () { module('App.Controllers.Products'); module('App.Services.Products'); }); beforeEach(inject(function (_$controller_, _$rootScope_, _$q_, _products_) { $rootScope = _$rootScope_; $q = _$q_; $controller = _$controller_; products = _products_; $scope = $rootScope.$new(); })); function setupController(product, resolve) { //Need a function so we can setup different instances of the controller var getProductsPromise = $q.defer(); //Set up our spies spyOn(products, 'getProducts').andReturn(getProductsPromise.promise); //Initialise the controller $controller('ProductsController', { $scope: $scope, products: products }); // Use $scope.$apply() to get the promise to resolve on nextTick(). // Angular only resolves promises following a digest cycle, // so we manually fire one off to get the promise to resolve, or in this // case we can choose through the parameters being passed in whether or // not to resolve the promise - thus covering our test cases. if(resolve) { $scope.$apply(function() { getProductsPromise.resolve(product); }); } else { $scope.$apply(function() { getProductsPromise.reject(); }); } } describe('Resolving and Rejecting the Promise', function () { it('should return the first PRODUCT when the promise is resolved', function () { setupController(PRODUCTS[0], PROMISE.resolve); // Set up our controller to return the first product and resolve the promise. expect('to return the first PRODUCT when the promise is resolved'); }); it('should return nothing when the promise is rejected', function () { setupController(PRODUCTS[0], PROMISE.reject); // Set up our controller to return first product, but not to resolve the promise. expect('to return nothing when the promise is rejected'); }); }); });
Это начинает чувствовать, как это должно быть! Мы можем издеваться над тем, что нам нужно, чтобы насмешлить, мы можем установить наше обещание разрешить и отклонить. Мы можем действительно проверить два возможных результата, и это чувствует себя хорошо.
Если вы заинтересованы в обучении больше о Angularjs, ознакомьтесь с этой страницей для различных видов ресурсов, которые помогут вам изучить Angularjs!
Этот учебник был первоначально опубликован автором на его блог Отказ Эта версия была отредактирована для ясности и может появиться отличаться от исходного поста.