2

我在单元测试和 AngularJS 方面很新,我有一些我无法解决的问题。我的一项测试不起作用。我试图通过影响一个值在我的测试中启动一个 location.path(),但在我的控制器中,location.path() 仍然有一个未定义的值。

这是我的控制器:

angular.module('...')
.controller('SignUpCtrl', ['$location', function ($location) {

    // Retrieve type of user
    var userType = $location.path().substr(9);
    if(userType == 'member'){
        userType = 'user';
    }

    console.log($location.path());
    console.log(userType);

    $scope.uType = userType;  ]);

这是我的测试模块:

describe('Controller: SignUpCtrl', function () {

// load the controller's module
beforeEach(module('...'));

var SignUpCtrl,
    scope,
    mockBackend,
    environments,
    location,
    store;

beforeEach(inject(function ($controller, $rootScope, $httpBackend,$location,_Environments_) {
    environments = _Environments_;
    mockBackend = $httpBackend;
    location = $location;
    scope = $rootScope.$new();

    SignUpCtrl = $controller('SignUpCtrl', {
        $scope: scope,
        $location: location
    });
}));

it('should come from the right location', function(){
    location.path('/sign-up/member');
    expect(location.path()).toBe('/sign-up/member');

    expect(scope.uType).toBe('user'); //Do not work
});

});

4

1 回答 1

2

You're trying to use unit testing to do something that can only really be achieved using End-to-End (or E2E) testing. Unit testing in AngularJS is designed to test the javascript within a given module or sub-module (such as a service, factory, directive, etc). However, things like page navigation or browser location really need to be tested in an end-to-end testing environment.

Because of that, your $location object won't have all the normal methods (like path, url, etc). The $location object ends up simply being a "mock" of the actual $location object that you'd get in your module. So, you just need to move your test case for it('should come from the right location', function(){ ... }) to an end-to-end test and then continue on with your other module-specific unit tests. After you do that, you can simplify the $controller by only grabbing the $scope variable, as in the following:

scope = $rootScope.new();
SignUpCtrl = $controller('SignUpCtrl', {$scope: scope});

The guide for E2E testing can be found at this link. It walks you through how to write good E2E tests. There is a really great framework available for doing angular E2E tests called Protractor. The info for that is at this link. Protractor will soon (in 1.2) replace Karma as a better way to handle E2E testing.

于 2013-10-14T17:05:39.820 回答