mercredi 2 septembre 2015

Jasmine testing custom http service

I have written an http service for my application and I would like to test it with Jasmine, but honestly it's my first time writing tests and I have really no idea of where to start by, can someone point me to the good direction ?

I have read a lot of tutorials on the basic Jasmine testing, and I get it, but my problem is more "what should I test, what are the usefull tests", and this http service is a perfect example for me to train with.

Below the http service I'd like to test:

angular.module('acme.services.http', [
    'config'
])

    .factory('http', function ($q, $http, $cacheFactory, API_BASEPATH) {

        // **********************************************************
        // Initialize
        // **********************************************************

        var cache = $cacheFactory('toip');

        // **********************************************************
        // Public API
        // **********************************************************

        return {
            get: get,
            post: post,
            put: put,
            update: update,
            destroy: destroy,
            flush: flush,
            resource: resource
        };

        // **********************************************************
        // Published methods
        // **********************************************************

        /**
         * Execute a GET http request.
         * @param path
         * @param config
         * @returns {qFactory.Deferred.promise|*}
         */
        function get(path, config) {
            return call('GET', path, null, config).then(extract);
        }

        /**
         * Execute a POST http request.
         * @param path
         * @param data
         * @param config
         * @returns {qFactory.Deferred.promise|*}
         */
        function post(path, data, config) {
            return call('POST', path, data, config).then(extract);
        }

        /**
         * Execute a PUT http request.
         * @param path
         * @param data
         * @param config
         * @returns {qFactory.Deferred.promise|*}
         */
        function put(path, data, config) {
            return call('PUT', path, data, config).then(extract);
        }

        /**
         * Execute an UPDATE http request.
         * @param path
         * @param data
         * @param config
         * @returns {qFactory.Deferred.promise|*}
         */
        function update(path, data, config) {
            return call('PUT', path, data, config).then(extract);
        }

        /**
         * Execute a DESTROY http request
         * @param path
         * @param config
         * @returns {qFactory.Deferred.promise|*}
         */
        function destroy(path, config) {
            return call('DELETE', path, null, config).then(extract);
        }

        /**
         *
         * @param path
         * @param config
         * @returns {qFactory.Deferred.promise|*}
         */
        function resource(path, config) {
            var ext = config.hasOwnProperty('ext') ? '.' + config.ext : '';
            return $http.get(toUrl(path) + ext, config).then(function (result) {
                return result.data;
            });
        }

        /**
         * Flush the HTTP cache.
         * @param {array} keys
         * @returns {*}
         */
        function flush() {
            var keys = angular.isArray(arguments[0]) ? arguments[0] : arguments;

            if (!keys.length) {
                return cache.removeAll();
            }
            angular.forEach(keys, function (path) {
                cache.remove(toUrl(path));
            });
        }

        // **********************************************************
        // Internal methods
        // **********************************************************

        /**
         * Execute an HTTP request and parse the result.
         * @param method
         * @param path
         * @param data
         * @param config
         * @returns {qFactory.Deferred.promise|*}
         */
        function call(method, path, data, config) {
            config = config || {};

            var defer = $q.defer();
            var url = toUrl(path);
            var handleData = (-1 !== ['PUT', 'POST'].indexOf(method));
            var dontCache;

            // don't cache if {cache: false} or if method != GET
            if (('undefined' !== typeof config && config.hasOwnProperty('cache') && false === config['cache']) ||
                (-1 == ['GET'].indexOf(method))) {
                dontCache = true;
            }

            // try to get data from cache
            var result = cache.get(url);

            if (!result || dontCache) {
                // add method & url
                config = angular.extend({
                    method: method,
                    url: url
                }, config);

                // force false here as we'll cache later
                config.cache = false;

                if (handleData && 'undefined' !== typeof data) {
                    config.data = data;
                }

                $http(config)
                    .success(function (result) {
                        if (!dontCache) {
                            cache.put(url, result);
                        }
                        defer.resolve(result);
                    })
                    .error(function (result) {
                        defer.reject(result['errors']);
                    });

            } else {
                defer.resolve(result);
            }

            // if method invoked were PUT/POST or DELETE, remove all cache
            if (-1 !== ['PUT', 'POST', 'DELETE'].indexOf(method)) {
                flush();
            }

            return defer.promise;
        }

        /**
         * Convert a dot notation path to an url.
         * @param path
         * @returns {string}
         */
        function toUrl(path) {
            if ('local:' === path.substring(0, 6)) {
                path = path.substring(6);
                return path.split('.').join('/');
            }

            return API_BASEPATH + '/' + path.split('.').join('/');
        }

        /**
         * Extract the HTTP request response.
         * @param response
         * @returns {*}
         */
        function extract(response) {
            if (false === response.success) {
                return $q.reject(response['errors'][0]);
            }
            return response['payload'];
        }
    });

Aucun commentaire:

Enregistrer un commentaire