在控制器茉莉花中测试.success和.error服务 [英] testing .success and .error of service in controller jasmine

查看:139
本文介绍了在控制器茉莉花中测试.success和.error服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在控制器中调用了服务的功能.下面是代码

I have a call to service's function in a controller. Below is the code

服务

(function () {
'use strict';
angular.module('MyApp')
    .service('MyService', ['$http', function ($http) {                                                  
        return {
            getMyData: function (extension) {                                        
                return $http.get('www.something.com');
            }                
        };
    }])
})();

控制器

var getMyData = function () {
            MyService.getMyData(extension).success(function (results) {
                //Some functionality here
            })
                .error(function (err, status) {
                //Some functionality here
            });
        }
$scope.Call=function(){
    getMyData();
}
$scope.Call();

现在,请告诉我如何模拟服务调用(可能与提供者一起使用).如何在完整的代码覆盖率下测试以上功能.

Now please tell me how to mock the service call (may be with providers). How to test the above functions with complete code coverage.

我的规格文件:

$provide.service("MyService", function () {
            this.getMyData= function () {
                var result = {
                    success: function (callback) {
                        return callback({ ServerFileName: "myserverfilename"});
                    },
                    error: function (callback) {
                        return callback({ ServerFileName: "myserverfilename" });
                    }
                };
                return result;
}           

//......
my controller initiation and other code

此代码未涵盖错误块并给出错误

This code is not covering error block and giving the error

Cannot read property 'error' of undefined

请帮助我如何在规范文件中编写/模拟服务的getMyData函数

Please help me how to write/mock the getMyData function of my service in my spec file

谢谢.

推荐答案

由于.success.error很旧并且已被.then(successCallback, errorCallback)替换,因此您应该考虑替换链接的.success.error调用只需调用.then方法,并使用两个回调作为参数:第一个是成功回调,第二个是错误回调.

Since .success and .error are old and have been replaced with .then(successCallback, errorCallback), you should consider replacing your chained .success and .error calls with a single call to the .then method with two callbacks as arguments to it: first being a success callback and second being an error callback.

如果这是您愿意做的,这是您的工作示例:

If that's what you're willing to do, here's your working example:

模块,服务和控制器

angular.module('MyApp', []);

angular.module('MyApp')
.service('MyService', ['$http', function ($http) {                                                  
    return {
        getMyData: function (extension) {                                        
            return $http.get('www.something.com');
        }                
    };
}]);

angular.module('MyApp')
.controller('MyAppController', ['$scope', function($scope){
    var extension = { foo: 'bar' };
    var getMyData = function () {
        MyService.getMyData(extension).then(function (results) {
            //Some functionality here
        }, function (err, status) {
            //Some functionality here
        });
    }
    $scope.Call=function(){
        getMyData();
    }
    $scope.Call();
}]);

和您的测试

describe('Controller: MyAppController', function(){
    beforeEach(module('MyApp'));
    var flag, extension, $q;
    extension = { foo: "bar" };
    beforeEach(inject(function($controller, $rootScope, _MyService_, _$q_) {
        $scope = $rootScope.$new();
        MyService = _MyService_;
        $q = _$q_;
        spyOn(MyService, 'getMyData').and.callFake(function(){
            return flag ? $q.when(): $q.reject();
        });
        MyAppController = $controller('MyAppController', {
            $scope: $scope,
            MyService: MyService
        });
    }));

    describe('function: Call', function() {
        //Text for Success Callback
        it('should implicitly call MyService.getMyData with an extension object', function() {
            flag = true;
            $scope.Call();
            expect(MyService.getMyData).toHaveBeenCalledWith(extension);
        });
        //Text for Error Callback
        it('should implicitly call MyService.getMyData with an extension object', function() {
            flag = false;
            $scope.Call();
            expect(MyService.getMyData).toHaveBeenCalledWith(extension);
        });
    });
});

更新: 我试图使类似的东西工作,但没有运气.由于.error()的呼叫已链接到.success()呼叫,并且只有在.success()被呼叫后才会被调用,因此它将永远不会到达.error()的呼叫,因此我们将无法进行模拟.error().因此,如果尝试这样做,我们总是会收到类似以下的错误:

UPDATE: I've tried making something like this to work but with no luck. Since .error()'s call is chained to .success() call, and that is something that will get called only after .success() has been called, it will never get to .error()'s call and we'll not be able to mock .error(). So if we try doing that, we'll always get an error like:

无法读取未定义的属性错误"

Cannot read property 'error' of undefined

因此,您可以使用注释/*istanbul ignore next*/跳过本文的这一部分,或切换到.then().

So either you can use the comment /*istanbul ignore next*/ to skip this part in the coverage, or switch to .then().

希望这会有所帮助.

这篇关于在控制器茉莉花中测试.success和.error服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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