angularJS服务的代码覆盖率

时间:2014-06-13 12:10:17

标签: angularjs unit-testing

我有一个正在调用服务的控制器。我想编写单元测试,以便了解then函数的成功和错误函数。

maApp.controller('editEmailAndPasswordController', 
                 ["$scope", "emailAndPasswordService",
    function editEmailAndPasswordController($scope, emailAndPasswordService) {
        $scope.EmailId = 'as@as.com';
        $scope.CurrentPassword = '';
        $scope.Success = false;

        $scope.save = function () {
            var request = {
                currentPassword: $scope.CurrentPassword,
                newEmailId: $scope.EmailId
            };
            emailAndPasswordService.save(request).then(function (data) {
                $scope.Success = true;
            }, function (data, status, header, config) {
                $scope.Success = false;
            });
        };
    }]);

这就是我所拥有的。我想要对失败条件进行另一次测试,但不知道如何设置模拟服务。

describe('Controllers', function () {
    var $scope, ctrl, controller, svc, def;
    describe('editEmailAndPasswordController', function () {

        beforeEach(function() {
            module('maApp');
        });

        beforeEach(inject(function ($controller, $rootScope, $q) {
            ctrl = $controller;
            svc = {
                save: function () {
                    def = $q.defer();
                    return def.promise;
                }
            };
            spyOn(svc, 'save').andCallThrough();
            $scope = $rootScope.$new();
            controller = ctrl('editEmailAndPasswordController', { $scope: $scope, emailAndPasswordService: svc });
        }));

        it('should set ShowEdit as false upon save', function () {
            $scope.ShowEdit = true;
            $scope.EmailId = 'newEmail';
            $scope.CurrentPassword = 'asdf1';

            $scope.save();
            expect($scope.EmailId).toBe('as@as.com');
            expect($scope.Success).toBe(true);
        });
    });
});

2 个答案:

答案 0 :(得分:3)

此代码存在一些实际问题。

  1. 不要打电话给#34; .andCallThrough()" - 这样你的测试取决于服务的实现,意味着你的控制器不是孤立的。主要想法是创建单元测试。

    svc = {save: jasmine.createSpy()};

    svc.save.andReturn(...);

  2. 您无法对expect($scope.EmailId).toBe('as@as.com');断言,因为您将代码中的值更改为$scope.EmailId = 'newEmail';

  3. 您可以为可读性创建2个私有方法

    function success(value) { var defer = q.defer(); defer.resolve(value); return defer.promise; }

    function failure(value){ var defer = q.defer(); defer.reject(value); return defer.promise; }

  4. 因此,在第一次测试中,您可以调用

    svc.save.andReturn(success());

    $scope.$digest()

    expect($scope.Success).toBeTruthy();

    在另一个测试中你会有同样的但是:

    svc.save.andReturn(failure());

    $scope.$digest()

    expect($scope.Success).toBeFalsy();

答案 1 :(得分:1)

在一种情况下,您希望承诺成功,因此您希望解决延迟:

$scope.save();

def.resolve('whatever');
$scope.$apply();

expect($scope.Success).toBe(true);
...

在另一种情况下,你希望承诺失败,所以你要拒绝延期:

$scope.save();

def.reject('whatever');
$scope.$apply();

expect($scope.Success).toBe(false);
...

the documentation中解释了这一点。