Angularjs:使用 spyOn 模拟 location.path() 进行单元测试

标签 angularjs unit-testing jasmine spyon

我已经读过这篇 post (和其他人)但我无法使这个简单的单元测试工作。我正在使用 Jasmine 的第 2 版。 我的工厂很简单:

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 是“家”)。

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

最佳答案

您的代码有两个主要问题。

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

第二个问题(尚未影响测试)是您使用测试的函数参数隐藏了 $location 变量 - 您将无法访问它,因为它始终未定义。删除此参数后,我可以测试是否使用 expect(...).toHaveBeenCalled() 调用了 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');
        });
    });
});

还有 JSFiddle (使用 Jasmine 1.3,但此示例中唯一的区别是您在 Jasmine 2 中调用 and.returnValue 而在 Jasmine 1.3 中调用 returnValue

关于Angularjs:使用 spyOn 模拟 location.path() 进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29994090/

相关文章:

javascript - 为什么在我的 Jasmine 测试中我的变量未定义 - Jasmine.js

javascript - 在 Flickr API 的 Tags 参数内传递变量

c# - 在单元测试中何时使用 Assert.Catch 与 Assert.Throws

javascript - Ionic 2 ion-navbar 返回参数

jquery 1.5 模拟 ajax

Python 数据类 : Mocking the default factory in a frozen Dataclass

javascript - 轨道 3.1 和 Jasmine : Including JavaScripts from gems

Angular Jasmine : Unit testing a method that is calling a service without doing actuall http call

javascript - 如何使用 Angular 或 JavaScript 更改 url

angularjs - 如何将背景图像添加到 ionic 侧面菜单