From fef793c27f281b9fe1df3b2860a0d3e3fb4d06af Mon Sep 17 00:00:00 2001 From: Daniel Pacak Date: Sat, 28 Mar 2015 16:24:54 +0100 Subject: [PATCH 1/5] Stubbing and Matching Promises --- README.md | 77 +++++++++++++++++++++++- assets/jasmine-promise-spy-strategies.js | 20 ++++++ 2 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 assets/jasmine-promise-spy-strategies.js diff --git a/README.md b/README.md index 43f886b2..6b28aa3b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # AngularJS Style Guide -*Opinionated AngularJS style guide for Liberty Seguros Compania de Seguros y Reaseguros S.A. (lu.pl) teams +*Opinionated AngularJS style guide for Liberty Seguros Compania de Seguros y Reaseguros S.A. (lu.pl) teams.* If you are looking for an opinionated style guide for syntax, conventions, and structuring AngularJS applications, then step right in. These styles are based on my development experience with [AngularJS](//angularjs.org), presentations, [Pluralsight training courses](http://pluralsight.com/training/Authors/Details/john-papa) and working in teams. @@ -2329,6 +2329,81 @@ Unit testing helps maintain clean code, as such I included some of my recommenda *Why?*: Sinon makes it easier to toggle between Jasmine and Mocha, if you want to try both. +### Stubbing and Matching Promises +###### [Style [C001](#style-c001)] + + - Use [jasmine promise matchers](https://github.com/bvaughn/jasmine-promise-matchers) along with [jasmine promise spy strategies](assets/jasmine-promise-spy-strategies.js]. + + *Why?*: To avoid cluttering and improve readability of your tests. + + ```javascript + angular + .module('calculator.direct.security', []) + .factory('authentication', authenticationFactory); + + authenticationFactory.$inject = ['$http']; + + function authenticationFactory($http) { + var service = { + getCurrentUser: getCurrentUser + }; + + function getCurrentUser() { + return $http.get('/authentication/current-user').then(function (response) { + // NB promise chaining in action + return response.data; + }); + } + + return service; + } + ``` + + ```javascript + describe('authentication service', function () { + + var $rootScope, $httpBackend, $q, authentication; + + beforeEach(function () { + module('calculator.direct.security'); + inject(function (_$rootScope_, _$httpBackend_, _$q_, _authentication_) { + $rootScope = _$rootScope_; + $httpBackend = _$httpBackend_; + $q = _$q_; + authentication = _authentication_; + }); + }); + + it('should return currently authenticated user', function () { + $httpBackend.whenGET('/authentication/current-user') + .respond({id: 123, email: 'mtyson@lu.pl'}); + + expect(authentication.getCurrentUser()) + .toBeResolvedWith({id: 123, email: 'mtyson@lu.pl'}); + + $httpBackend.flush(); + $rootScope.$digest(); // actually resolve promise(s) + }); + + it('should stub/mock returned promise', function () { + spyOn(authentication, 'getCurrentUser').and + .returnResolvedPromise($q, {id: 123, email: 'mtyson@lu.pl'}); + + expect(authentication.getCurrentUser()) + .toBeResolvedWith({id: 123, email: 'mtyson@lu.pl'}); + + $rootScope.$digest(); // actually resolve promise(s) + }); + + }); + + ``` + + - Note: The `toBeResolvedWith` matcher provided by [jasmine promise matchers](https://github.com/bvaughn/jasmine-promise-matchers), + and the `returnResolvedPromise` spy strategy defined by [jasmine promise spy strategies](assets/jasmine-promise-spy-strategies.js]. + + - Note: Similarly, you can use the `toBeRejectedWith` matcher as well as the `returnRejectedPromise` spy strategy. + ### Headless Browser ###### [Style [Y194](#style-y194)] diff --git a/assets/jasmine-promise-spy-strategies.js b/assets/jasmine-promise-spy-strategies.js new file mode 100644 index 00000000..3b3f5f35 --- /dev/null +++ b/assets/jasmine-promise-spy-strategies.js @@ -0,0 +1,20 @@ +'use strict'; + +beforeEach(function () { + + jasmine.SpyStrategy.prototype.returnResolvedPromise = function (promiseApi, resolvedValue) { + return this.callFake(function () { + var deferred = promiseApi.defer(); + deferred.resolve(resolvedValue); + return deferred.promise; + }); + }; + + jasmine.SpyStrategy.prototype.returnRejectedPromise = function (promiseApi, rejectValue) { + return this.callFake(function () { + var deferred = promiseApi.defer(); + deferred.reject(rejectValue); + return deferred.promise; + }); + }; +}); From 1a92268f176ee9f59971dfc98cf01b5328e91c52 Mon Sep 17 00:00:00 2001 From: Daniel Pacak Date: Sat, 28 Mar 2015 17:29:39 +0100 Subject: [PATCH 2/5] Stubbing and Matching Promises --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6b28aa3b..99c27d74 100644 --- a/README.md +++ b/README.md @@ -2332,7 +2332,7 @@ Unit testing helps maintain clean code, as such I included some of my recommenda ### Stubbing and Matching Promises ###### [Style [C001](#style-c001)] - - Use [jasmine promise matchers](https://github.com/bvaughn/jasmine-promise-matchers) along with [jasmine promise spy strategies](assets/jasmine-promise-spy-strategies.js]. + - Use [jasmine promise matchers](https://github.com/bvaughn/jasmine-promise-matchers) along with [jasmine promise spy strategies](assets/jasmine-promise-spy-strategies.js?raw=true]. *Why?*: To avoid cluttering and improve readability of your tests. @@ -2399,10 +2399,10 @@ Unit testing helps maintain clean code, as such I included some of my recommenda ``` - - Note: The `toBeResolvedWith` matcher provided by [jasmine promise matchers](https://github.com/bvaughn/jasmine-promise-matchers), - and the `returnResolvedPromise` spy strategy defined by [jasmine promise spy strategies](assets/jasmine-promise-spy-strategies.js]. + - Note: The `toBeResolvedWith` matcher provided by [jasmine promise matchers](https://github.com/bvaughn/jasmine-promise-matchers), + and the `returnResolvedPromise` spy strategy defined by [jasmine promise spy strategies](assets/jasmine-promise-spy-strategies.js?raw=true]. - - Note: Similarly, you can use the `toBeRejectedWith` matcher as well as the `returnRejectedPromise` spy strategy. + - Note: Similarly, you can use the `toBeRejectedWith` matcher as well as the `returnRejectedPromise` spy strategy. ### Headless Browser ###### [Style [Y194](#style-y194)] From 4c37365d719392dfc500ee4f86cca6041d4e0090 Mon Sep 17 00:00:00 2001 From: Daniel Pacak Date: Sat, 28 Mar 2015 17:44:39 +0100 Subject: [PATCH 3/5] Stubbing and Matching Promises --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 99c27d74..7d1f2f5a 100644 --- a/README.md +++ b/README.md @@ -2332,7 +2332,7 @@ Unit testing helps maintain clean code, as such I included some of my recommenda ### Stubbing and Matching Promises ###### [Style [C001](#style-c001)] - - Use [jasmine promise matchers](https://github.com/bvaughn/jasmine-promise-matchers) along with [jasmine promise spy strategies](assets/jasmine-promise-spy-strategies.js?raw=true]. + - Use [jasmine promise matchers](https://github.com/bvaughn/jasmine-promise-matchers) along with [jasmine promise spy strategies](assets/jasmine-promise-spy-strategies.js?raw=true). *Why?*: To avoid cluttering and improve readability of your tests. @@ -2348,6 +2348,11 @@ Unit testing helps maintain clean code, as such I included some of my recommenda getCurrentUser: getCurrentUser }; + /** + * @name getCurrentUser + * @desc Returns currently authenticated user. + * @returns {Object.} resolved to object representing authenticated user or null + */ function getCurrentUser() { return $http.get('/authentication/current-user').then(function (response) { // NB promise chaining in action @@ -2400,7 +2405,7 @@ Unit testing helps maintain clean code, as such I included some of my recommenda ``` - Note: The `toBeResolvedWith` matcher provided by [jasmine promise matchers](https://github.com/bvaughn/jasmine-promise-matchers), - and the `returnResolvedPromise` spy strategy defined by [jasmine promise spy strategies](assets/jasmine-promise-spy-strategies.js?raw=true]. + and the `returnResolvedPromise` spy strategy defined by [jasmine promise spy strategies](assets/jasmine-promise-spy-strategies.js?raw=true). - Note: Similarly, you can use the `toBeRejectedWith` matcher as well as the `returnRejectedPromise` spy strategy. From 3da8cf972b8a8f4ea2b1652cb8471abb475b3d2e Mon Sep 17 00:00:00 2001 From: Daniel Pacak Date: Sat, 28 Mar 2015 17:50:54 +0100 Subject: [PATCH 4/5] Stubbing and Matching Promises --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 7d1f2f5a..f2b31a0b 100644 --- a/README.md +++ b/README.md @@ -2337,6 +2337,7 @@ Unit testing helps maintain clean code, as such I included some of my recommenda *Why?*: To avoid cluttering and improve readability of your tests. ```javascript + // src/main/calculator/direct/security/authentication.js angular .module('calculator.direct.security', []) .factory('authentication', authenticationFactory); @@ -2365,6 +2366,7 @@ Unit testing helps maintain clean code, as such I included some of my recommenda ``` ```javascript + // src/test/calculator/direct/security/authentication.spec.js describe('authentication service', function () { var $rootScope, $httpBackend, $q, authentication; From e6e6f3f142042502f310275dcad3b945e6c951fb Mon Sep 17 00:00:00 2001 From: Daniel Pacak Date: Sat, 28 Mar 2015 17:55:09 +0100 Subject: [PATCH 5/5] Stubbing and Matching Promises --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f2b31a0b..5ee5b2cf 100644 --- a/README.md +++ b/README.md @@ -2332,7 +2332,7 @@ Unit testing helps maintain clean code, as such I included some of my recommenda ### Stubbing and Matching Promises ###### [Style [C001](#style-c001)] - - Use [jasmine promise matchers](https://github.com/bvaughn/jasmine-promise-matchers) along with [jasmine promise spy strategies](assets/jasmine-promise-spy-strategies.js?raw=true). + - Use [jasmine promise spy strategies](assets/jasmine-promise-spy-strategies.js?raw=true) along with [jasmine promise matchers](https://github.com/bvaughn/jasmine-promise-matchers). *Why?*: To avoid cluttering and improve readability of your tests.