与AngularJS和Jasmine惩戒HTTP服务单元测试 [英] Mocking HTTP service unit test with AngularJS and Jasmine

查看:108
本文介绍了与AngularJS和Jasmine惩戒HTTP服务单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图建立一个模拟服务,使我的单元测试可以验证某些函数被调用,并相应地更新。不幸的是,我不能得到这个工作。

I am attempting to build a mock service so that my unit tests can verify certain functions are called and updated accordingly. Unfortunately I cannot get this to work.

即时通讯目前得到一个错误不确定是不是在这条线的函数

Im currently getting an error undefined is not a function on this line:

spyOn(statusService, 'getModuleStatus').andCallThrough();

我的实际服务是这样的:

My actual service looks like this:

serviceStatusServices.factory('serviceStatusAppAPIservice', function ($http) {

    var serviceStatusAppAPI = {};

    serviceStatusAppAPI.getModuleStatus = function () {
        return $http({
            method: 'JSON',
            url: '/settings/getservicestatusandconfiguration'
        });
    }

    serviceStatusAppAPI.setModuleStatus = function (module) {
        return $http({
            method: 'POST',
            url: '/settings/setservicestatusandconfiguration',
            data: { moduleId: module.ModuleId, configData: module.ConfigValues }
        });
    }

    return serviceStatusAppAPI;
});

我的更新功能

serviceStatusControllers.controller('serviceStatusController', ['$scope', 'serviceStatusAppAPIservice', '$filter', '$timeout', function ($scope, serviceStatusAppAPIservice, $filter, $timeout) {

    $scope.update = function () {
        $scope.loading = true;
        serviceStatusAppAPIservice.getModuleStatus().then(function (response) {

            $scope.modules = $filter('orderBy')(response.data.moduleData, 'ModuleName')
            ...

我的测试看起来像这样

My tests look like this

describe('ServiceStatusController', function () {
    beforeEach(module("serviceStatusApp"));

    var scope;
    var statusService;
    var controller;
    var q;
    var deferred;

    // define the mock people service
    beforeEach(function () {
        statusService = {
            getModuleStatus: function () {
                deferred = q.defer();
                return deferred.promise;
            }
        };
    });

    // inject the required services and instantiate the controller
    beforeEach(inject(function ($rootScope, $controller, $q) {
        scope = $rootScope.$new();
        q = $q;
        controller = $controller('serviceStatusController', { 
                     $scope: scope, serviceStatusAppAPIservice: statusService });
    }));

    describe("$scope.update", function () {
        it("Updates screen", function () {
            spyOn(statusService, 'getModuleStatus').andCallThrough();

            scope.update();

            deferred.resolve();

            expect(statusService.getModuleStatus).toHaveBeenCalled();
            expect(scope.modules).not.toBe([]);
        });
    });
});

另外,我如何通过从服务调用者返回的模拟数据。目前在我的模型我 serviceStatusAppAPI.getModuleStatus(数据)然后用数据。数据脱身返回的JSON。

Also, how do I pass any mock data returned from the service to the caller. Currently in my model I do serviceStatusAppAPI.getModuleStatus(data) then use data.Data to get out the returned JSON.

推荐答案

我认为如果你正在做这样的事情在你CTRL

I assume if you are doing something like this in your ctrl

scope.update = function() {
    serviceStatusAppAPIservice.setModuleStatus(url).then(function (data) {
        scope.modules = data;
    })    
};

服务返回的承诺

.factory('serviceStatusAppAPI', function($http, $q) {
        return {
            getModuleStatus: function() {
                var defer = $q.defer();
                $http({method: 'GET', url: '/settings/getservicestatusandconfiguration'})
                    .success(function(data, status, headers, config) {
                        // this callback will be called asynchronously
                        // when the response is available
                        defer.resolve(data);
                    })
                    .error(function(data, status, headers, config) {
                        // called asynchronously if an error occurs
                        // or server returns response with an error status.
                        window.data = data;
                    });

                return defer.promise;
            }
        };
    });

因此​​,在您控制器你会得到这样的数据。

So in you controller you will get data like this

serviceStatusAppAPI.getModuleStatus().then(function (data) {
    $scope.modules = $filter('orderBy')(data.moduleData, 'ModuleName')
})

这是你如何可以运行你的单元测试用例

This is how you can run your unit test case

beforeEach(function() {

    var statusService = {};

    module('myApp', function($provide) {
        $provide.value('serviceStatusAppAPIservice', statusService);
    });

    statusService.modalStatus = {
        moduleData: [{ModuleName: 'abc'}, {ModuleName: 'def'}]
    };

    inject(function ($q) {
        statusService.setModuleStatus = function () {
            var defer = $q.defer();

            defer.resolve(this.modalStatus);

            return defer.promise;
        };

        statusService.getModuleStatus = function () {
            var defer = $q.defer();

            defer.resolve(this.modalStatus);

            return defer.promise;
        };

    });
});

beforeEach(inject(function ($rootScope, $controller, _$stateParams_) {
    scope = $rootScope.$new();
    stateParams = _$stateParams_;
    controller = $controller;
}));

var myCtrl = function() {
    return controller('ServiceStatusController', {
                $scope: scope,
            });
};

it('should load status', function () {
    myCtrl();
    scope.update();
    scope.$digest();
    expect(scope.modules).toBe({
        status: 'active'
    });
});

这篇关于与AngularJS和Jasmine惩戒HTTP服务单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆