【问题标题】:How to mock $rootScope method defined in controller?如何模拟控制器中定义的 $rootScope 方法?
【发布时间】:2016-02-15 13:49:52
【问题描述】:

我正在为服务编写单元测试,但 $rootScope.hideLogout(); 方法有问题(请参阅下面的服务代码),因为它是在控制器中定义的,而我没有从我的测试中可以访问(至少我是这么认为的)这个控制器,我得到了错误:

对象不支持属性或方法'hideLogout'

这是我的测试:

it('should logout when player is in the system', function () {
        var user = {
            name: 'player name',
            password: 'password'
        };
        var userData = {
            access_token: 'token',
            token_type: 'bearer',
            expires_in: 1209599,
            userName: 'Player@maildomain.com',
            issued: "Fri, 12 Feb 2016 12:02:37 GMT",
            expires: 'Thu, 25 Feb 2016 13:22:45 GMT',
            userId: 2,
            accountType: 'Player',
            certifiedForAccess: true
        }
        localStorage.setItem('userAuth', JSON.stringify(user));
        localStorage.setItem('tokenKey', JSON.stringify(userData));
        localStorage.setItem('userId', userData.userId);

        authSvc.logOut(true, function() {}); // not sure about callback, so decided to put empty function for now
        var resultToken = localStorage.getItem('tokenKey');

        expect(localStorage.getItem('tokenKey')).toBeNull();
        expect(localStorage.getItem('userAuth')).toBeNull();
        expect(localStorage.getItem('userId')).toBeNull();
    });

我的 beforeEach() 函数:

beforeEach(function() {

    module('app');
    inject(function (_AuthService_, $q, $rootScope, $httpBackend, $state, _config_, _messages_) {
        scope = $rootScope;

        authSvc = _AuthService_;
        httpBackend = $httpBackend;
        config = _config_;
    });
});

要测试的服务方法:

function logOut(logoutAnyway, cancelLogoutCallback) {
        if (logoutAnyway || !svc.isAdministrator()) {
            $rootScope.hideLogout(true);
            localStorage.removeItem(userIdKey);
            localStorage.removeItem(userAuthKey);
            localStorage.removeItem(tokenKey);
            $state.go('login');
            svc.fakeUserId = null;
        } else {
            $rootScope.showLogout(cancelLogoutCallback);
        }
    }

你能给我一些关于如何处理它的方向吗?

【问题讨论】:

  • 把函数放在 $rootScope 上是个坏主意。如果这些实用功能改变了页面视图,请将它们放入指令中。否则,将它们放入服务中。
  • @MBielski 我无法更改代码,我不是开发人员,只是测试人员。但是我会问开发人员是否可以更改它。有什么方法可以避免代码更改并按原样进行测试?
  • 您的开发人员应该知道不要像那样使用 $rootScope。努力改变。它是不可测试和不可维护的。

标签: angularjs unit-testing mocking jasmine


【解决方案1】:

尝试在您的测试中使用scope = $rootScope.new()

更新

您还需要在方法上使用 Jasmine 的spyOn

spyOn(scope , 'hideLogout');
spyOn(scope , 'showLogout');

更新 2

scope = $rootScope.new() 之后尝试模拟$rootScope 上的两个方法

scope.hideLogout = function () {};
scope.showLogout = function () {};

然后添加spyOn部分代码

【讨论】:

  • 我已经试过了,把这 spyOn 行放到 beforeEach() 中,但是没有看到这个方法:“method hideLogout( ) 不存在”。当我将其放入测试本身时也是如此。
  • 仍然没有进展:(如你所说放置函数,尝试spyOn有和没有.and.callThrough()但测试运行器说Object不支持属性或方法'hideLogout()'
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-08
  • 2014-04-07
  • 1970-01-01
  • 1970-01-01
  • 2019-05-14
  • 1970-01-01
相关资源
最近更新 更多