AngularJS Jasmine测试:范围变量始终未定义

时间:2014-04-08 08:23:10

标签: javascript angularjs undefined jasmine karma-runner

我对Javascript测试非常陌生,目前正在尝试测试控制器功能。 该函数调用一个服务方法,该方法从Web sql db中检索数据。

这是我的控制器功能的一部分(它包含2个回调,一个用于成功,另一个用于错误):

    $scope.getLocations = function () {
        LocationDbService.getAll(
            //Success
            function (tx, results) {

                $scope.numberOfLocations = results.rows.length;
                ...
            },
            //Error
            function () {
                console.log("Error");
            });
    }

测试:

it('we should be able to retrieve all stored locations',
    function () {
        expect(scope.numberOfLocations).toBeUndefined();
        scope.getLocations();
        expect(scope.numberOfLocations).toBeDefined();
    });

beforeEach test:

var ctrl, scope, location, locationDbService;
// inject the $controller and $rootScope services
// in the beforeEach block
beforeEach(inject(function ($controller, $rootScope, $location, LocationDbService) {
    // Create a new scope that's a child of the $rootScope
    scope = $rootScope.$new();
    // Create the controller
    ctrl = $controller('LocationsCtrl', {
        $scope: scope
    });
    location = $location;
    locationDbService = LocationDbService;
}));

控制器标题:

.controller('LocationsCtrl', function ($scope, $location, LocationDbService) {

当我在浏览器中运行应用程序时(或在我的智能手机上,它是一个混合应用程序)一切正常,但是当我运行测试时,我得到以下内容:

Test failure

有人知道为什么范围变量仍未定义? 提前谢谢!

1 个答案:

答案 0 :(得分:1)

在实例化控制器时,您还应该注入所需的任何其他服务。

AngularJS有一个很酷的技巧,你可以在名字中使用下划线:

  beforeEach(inject(function ($controller, $rootScope, _$location_, _LocationDbService_) {
        // Create a new scope that's a child of the $rootScope
        scope = $rootScope.$new();
        // Create the controller
        ctrl = $controller('LocationsCtrl', {
            $scope: scope,
            $location : _$location_,
            LocationDbService : _LocationDbService_
        });
        location = _$location_; //thx to the underscores you could use '$location' as name instead of 'location'
        locationDbService = _LocationDbService_;
    }));

接下来你应该模拟服务电话:

it('should be able to retrieve all stored locations',
    function () {
        spyOn(locationDbService , 'getAll').andCallFake(function (success, fail) {
             var results = {};
             results.rows = new Array(5);
             success(null, results);
        });
        expect(scope.numberOfLocations).toBeUndefined();
        scope.getLocations();
        expect(scope.numberOfLocations).toBe(5);
    });

该服务应该有自己的测试。