在Karma中测试Angular $ window.location.href

uns*_*age 4 javascript unit-testing mocha.js angularjs karma-runner

我试图弄清楚如何正确地将$ window服务注入我的角度控制器,然后进行测试以确保它适当地重定向.目前,我收到一个错误说明undefined is not a constructor (evaluating 'expect(window.location.href).toEqual('/profile')').我的角度控制器的片段如下:

login.submitLogin = function(){
    LoginFactory.loginUser(login.dataset)
        .then(function(response){
            $window.location.href = '/profile'
        },function(response) {
            login.errorMessage = response.data.message;
        });
};
Run Code Online (Sandbox Code Playgroud)

我在Karma的单元测试如下:

describe('Login Controller', function() {

    var controller, window;

    beforeEach(angular.mock.module('app'));

    beforeEach(inject(function(_$controller_, _$window_){
        window = _$window_;
        controller = _$controller_('LoginCtrl',window);
    }));

    describe('Login', function() {

        it('expects controller to be defined', function(){
            expect(controller).to.be.defined;
        });

        it('expects to be redirected after login', function() {
            controller.dataset.username = 'username';
            controller.dataset.password = 'password';
            controller.submitLogin();
            expect(window.location.href).toEqual('/profile');
        });
    });
});
Run Code Online (Sandbox Code Playgroud)

And*_*nka 5

一种解决方案是在测试中使用mock(覆盖)$ window服务:

    beforeEach(function () {
        module(function($provide) {
            $provide.value('$window', {
                location: {href: ''}
            });
        });
    });

    beforeEach(inject(function(_$controller_, _$window_){
        window = _$window_;
        controller = _$controller_('LoginCtrl',window);
    }));
Run Code Online (Sandbox Code Playgroud)

然后通过以下方式检查已分配给$ window.location.href的内容:

expect(window.location.href).toEqual('/profile');
Run Code Online (Sandbox Code Playgroud)

如果LoginFactory.loginUser向服务器发出请求,您还需要使用$ httpBackend:

    it('expects to be redirected after login', function() {
        var mockedResponse = {};

        controller.dataset.username = 'username';
        controller.dataset.password = 'password';

        $httpBackend.whenPOST('/api/login/').respond(mockedResponse);
        controller.submitLogin();
        $httpBackend.flush();

        expect(window.location.href).toEqual('/profile');
    });
Run Code Online (Sandbox Code Playgroud)