模拟$ http Angular Ionic

时间:2015-06-26 13:26:52

标签: angularjs unit-testing ionic

我正在使用Ionic,我想在我的httpClient上进行单元测试

describe('send', function() {
    var $httpBackend, userManager, apiClient;

    beforeEach(inject(function($injector) {
        $httpBackend = $injector.get('$httpBackend');
        apiClient = new APIClient($httpBackend, userManager);
    }));

    it ('Should check if send() exists', function() {
        expect(apiClient.send).toBeDefined();
    });

    it ('Should send GET request', function(done) {
        var url = '/';

        $httpBackend.expect('GET', url, {}, {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}).respond({});
        apiClient.send({
            url: url,
            success: function(data, status) {
                console.log(data);
                console.log(status);
                done();
            },
            error: function(data, status) {
                console.log(data);
                console.log(status);
                done();
            }
        });
    });
});

但我一直有这个错误

Error: Unexpected request: [object Object] undefined
Expected GET /

我在投入角度模拟之前添加console.log,我有

LOG: Object{method: 'GET', url: '/', headers: Object{Content-Type: 'application/x-www-form-urlencoded; charset=UTF-8'}, data: Object{}}

我也只尝试$httpBackend.expect('GET', url)并且我有dame错误

我尝试了$httpBackend.when('GET', url),我有

Error: Unexpected request: [object Object] undefined
No more request expected

以下是APIClient的完整代码:

/**
 * Util
 *
 * @constructor
 */
var APIClient = function($http, UserManager)
{
    this.userManager = UserManager;

    this.tokenUrl = AppSettings.baseApiUrl + '/oauth/v2/token';
    this.clientId = AppSettings.clientId;
    this.clientSecret = AppSettings.clientSecret;

    this.accessTokenKey = 'access_token';
    this.refreshTokenKey = 'refresh_token';
    this.expireTokenKey = 'expires_in';

    var that = this;

    /**
     *
     * @param {{method:{string}, url:{string}, headers:{}, data:{}, success:function({}, int), error:function({}, int), oauth:{boolean}}} customerData
     */
    this.send = function(customerData)
    {
        var data = {
            method: 'GET',
            url: null,
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
            },
            data: {},
            file: null,
            success: function(){},
            error: function(){},
            oauth: false
        };

        for (var attrName in customerData) {
            if (customerData.hasOwnProperty(attrName)) {
                data[attrName] = customerData[attrName];
            }
        }

        var successCallback = data.success;
        var errorCallback = data.error;

        var oAuthStatus = 1;

        if (data.oauth) {
            oAuthStatus = 0;
            this.getToken(function(success, message){
                if (success) {
                    data.url = that.setGetParameter(
                        data.url,
                        that.accessTokenKey,
                        message
                    );
                    oAuthStatus = 1;
                } else {
                    errorCallback(message);
                    oAuthStatus = 2;
                }
            });
        }

        var intvl = setInterval(function() {
            if (oAuthStatus != 0) {
                clearInterval(intvl);

                if (oAuthStatus == 1) {
                    if (data.file !== null) {
                        sendFile(data, successCallback, errorCallback);
                    } else {

                        var tmpData = '';
                        for (var key in data.data) {
                            if (data.data.hasOwnProperty(key)) {
                                data.url = that.setGetParameter(data.url, key, data.data[key]);
                            }
                        }

                        if (data.method !== 'GET') {
                            data.data = tmpData.substring(1);
                        } else {
                            data.data = {};
                        }

                        sendRequest(data, successCallback, errorCallback);
                    }
                }
            }
        }, 100);
    };

    /**
     *
     * @param {function(boolean, {})} callback
     */
    this.getToken = function(callback)
    {
        if (!this.isToken()) {
            this.loadToken(function(success, data){
                if (success) {
                    callback(true, that.getAccessToken());
                } else {
                    callback(false, data);
                }
            });
        }else if (this.isTokenExpired()) {
            this.refreshToken(function(success, data){
                if (success) {
                    callback(true, this.getAccessToken());
                } else {
                    callback(false, data);
                }
            });
        } else {
            callback(true, this.getAccessToken());
        }
    };

    /**
     *
     * @param {function(boolean, data)} callback
     */
    this.loadToken = function(callback)
    {
        if (!this.userManager.isCurrent()) {
            throw {
                key: 'api_client_user_not_found',
                message: 'User not found'
            }
        }

        var user = this.userManager.getCurrent();

        this.send({
            method: 'GET',
            url: this.tokenUrl,
            data: {
                client_id: this.clientId,
                client_secret: this.clientSecret,
                username: user.getUsername(),
                password: user.getPassword(),
                grant_type: 'password'
            },
            success: function (data) {
                that.updateToken(data);
                callback(true, data);
            },
            error: function (data) {
                callback(false, data)
            }
        });
    };

    /**
     *
     * @param {function(boolean, {})} callback
     */
    this.refreshToken = function(callback)
    {
        if (!this.userManager.isCurrent()) {
            throw {
                key: 'api_client_user_not_found',
                message: 'User not found'
            }
        }

        this.send({
            method: 'GET',
            url: this.tokenUrl,
            data: {
                client_id: this.clientId,
                client_secret: this.clientSecret,
                refresh_token: this.getRefreshToken(),
                grant_type: 'refresh_token'
            },
            success: function (data) {
                that.updateToken(data);
                callback(true, data)
            },
            error: function (data) {
                callback(false, data)
            }
        });
    };

    /**
     *
     * @param {{access_token:{string}, refresh_token:{string}, expires_in:{string}}} data
     */
    this.updateToken = function(data)
    {
        window.localStorage.setItem(this.accessTokenKey, data[this.accessTokenKey]);
        window.localStorage.setItem(this.refreshTokenKey, data[this.refreshTokenKey]);

        var t = new Date();
        t.setSeconds(t.getSeconds() + data[this.expireTokenKey]);

        window.localStorage.setItem(this.expireTokenKey, t.getTime());
    };

    /**
     * Clear api tokens
     */
    this.clearToken = function()
    {
        window.localStorage.removeItem(this.accessTokenKey);
        window.localStorage.removeItem(this.refreshTokenKey);
        window.localStorage.removeItem(this.expireTokenKey);
    };

    /**
     *
     * @returns string
     */
    this.getAccessToken = function()
    {
        return window.localStorage.getItem(this.accessTokenKey);
    };

    /**
     *
     * @returns string
     */
    this.getRefreshToken = function()
    {
        return window.localStorage.getItem(this.refreshToken);
    };

    /**
     *
     * @returns string
     */
    this.getTokenExpiration = function()
    {
        return window.localStorage.getItem(this.expireTokenKey);
    };

    /**
     *
     * @returns {boolean}
     */
    this.isToken = function()
    {
        return null !== this.getAccessToken();
    };

    /**
     *
     * @returns {boolean}
     */
    this.isTokenExpired = function()
    {
        var t = new Date;

        return t.getTime() > this.getTokenExpiration()
    };

    /**
     *
     * @param {string} url
     * @param {string} paramName
     * @param {string} paramValue
     * @returns {string}
     */
    this.setGetParameter = function(url, paramName, paramValue)
    {
        if (url.indexOf(paramName + "=") >= 0)
        {
            var prefix = url.substring(0, url.indexOf(paramName));
            var suffix = url.substring(url.indexOf(paramName));
            suffix = suffix.substring(suffix.indexOf("=") + 1);
            suffix = (suffix.indexOf("&") >= 0) ? suffix.substring(suffix.indexOf("&")) : "";
            url = prefix + paramName + "=" + paramValue + suffix;
        }
        else
        {
            if (url.indexOf("?") < 0)
                url += "?" + paramName + "=" + paramValue;
            else
                url += "&" + paramName + "=" + paramValue;
        }
        return url;
    };

    function sendRequest(data, successCallback, errorCallback) {
        $http({
            method: data.method,
            url: data.url,
            headers: data.headers,
            data: data.data
        }).success(function(data, status){
            successCallback(data, status);
        }).error(function(data, status){
            errorCallback(data, status);
        });
    }

    function sendFile(data, successCallback, errorCallback) {

        var options = new FileUploadOptions();
        options.fileKey="file";
        options.fileName="file";
        options.params = data.data;

        var ft = new FileTransfer();
        ft.upload(data.file, data.url, uploadSuccess, uploadError, options);
        function uploadSuccess(r) {
            result = JSON.parse(r.response);
            successCallback(result, true);
        }
        function uploadError(error) {
            errorCallback(error, true)
        }
    }

};

angular.module('api.client', []).factory('APIClient', ['$http', 'UserManager', function($http, UserManager)
{
    var client = new APIClient($http, UserManager);

    return {
        send: function(data)
        {
            return client.send(data);
        },
        clearToken: function()
        {
            client.clearToken();
        }
    }

}]);

1 个答案:

答案 0 :(得分:1)

  

您的错误发生是因为您需要查询$ http(&#39; GET&#39;,&#39; /&#39;)   永远不会发生!

我不确定如何管理您传递$http依赖项参数的情况。 $ httpBackend单独管理$ http调用的替换,因此期望代码中有$ http。

为了保持您的代码原样,我将$ http注入您的beforeEach,但我从未测试过。

 beforeEach(inject(function($injector) {
        $httpBackend = $injector.get('$httpBackend');
        var $http = $injector.get('$http');
        apiClient = new APIClient($http, userManager);
    }));
  

我宁愿修改我的APIClient而不接受$ http参数,因此angularJS $ httpBackend的标准机制会适用

此外,请不要忘记使用:$httpBackend.flush()使用经过培训的回复来刷新所有待处理的请求。