Angularjs:mock location.path(),带有用于单元测试的spyOn

Angularjs:mock location.path(),带有用于单元测试的spyOn,angularjs,unit-testing,jasmine,spyon,Angularjs,Unit Testing,Jasmine,Spyon,我已经读过这篇文章(和其他文章),但我没有设法让这个简单的单元测试工作起来。我用的是茉莉花的第二版。 我的工厂很简单: angular.module('myApp') .factory('detectPath', function ($location, $rootScope) { 'use strict'; var locationPath = $location.path() function getPath () {

我已经读过这篇文章(和其他文章),但我没有设法让这个简单的单元测试工作起来。我用的是茉莉花的第二版。 我的工厂很简单:

angular.module('myApp')
    .factory('detectPath', function ($location, $rootScope) {
        'use strict';
        var locationPath = $location.path()
        function getPath () {
            if (locationPath === '/') {
                locationPath = 'home';
            } else {
                locationPath = '';
            }
            $rootScope.path = locationPath;
        }
        getPath();
        return locationPath;
    });
我的单元测试也很简单:

'use strict';
describe('Factory: detectPath', function () {
    var detectPath, $rootScope, $location;

    beforeEach(module('myApp'));
    beforeEach(inject(function (_detectPath_, _$rootScope_, _$location_) {
        detectPath = _detectPath_;
        $rootScope = _$rootScope_;
        $location = _$location_;
        spyOn($location, 'path').and.returnValue('/');
    }));

    it('should return pathName', function ($location) {
        expect($rootScope.path).toBe('home');
    });
});
这没有通过测试(我得到的错误是false为“home”)

我做错了什么?
是否有方法验证spyOn是否已被调用(仅一次)?

您的代码存在两个主要问题

首先,在设置spy之前执行
getPath()
函数。您应该在每次之前的
中设置spy,或者在测试中注入您的工厂(我选择了第二种解决方案)

第二个问题(目前还不影响测试)是,您使用测试的函数参数隐藏了
$location
变量-您将无法访问它,因为它始终是未定义的。在我删除这个arg之后,我可以测试spy是否被调用

以下是工作代码:

describe('Factory: detectPath', function () {
    var detectPath, $rootScope, $location;

    beforeEach(module('myApp'));
    beforeEach(inject(function (_$rootScope_, _$location_) {
        $rootScope = _$rootScope_;
        $location = _$location_;
        spyOn($location, 'path').and.returnValue('/');
    }));

    it('should return pathName', function () {
        inject(function (detectPath) {
            expect($location.path).toHaveBeenCalled();
            expect($rootScope.path).toBe('home');
        });
    });
});
和(使用Jasmine 1.3,但本示例中唯一的区别是在Jasmine 2中调用
和.returnValue
,在Jasmine 1.3中调用
returnValue