gpt4 book ai didi

javascript - 如何使用 ui-router 测试依赖于服务的 AngularJS Controller ?

转载 作者:行者123 更新时间:2023-12-04 00:53:47 26 4
gpt4 key购买 nike

我的测试是:

(function() {
describe('Login Controller', function() {
beforeEach(module('myApp'));
beforeEach(inject(function($injector) {
var $controller, $httpBackend, $q, userServiceMock;
self.$rootScope = $injector.get('$rootScope');
self.$scope = $rootScope.$new();
self.$state = $injector.get('$state');
$q = $injector.get('$q');
$httpBackend = $injector.get('$httpBackend');
$controller = $injector.get('$controller');
userServiceMock = {
login: function(auth) {
self.deferred = $q.defer();
console.log("HERE!");
return self.deferred.promise;
}
};
self.createController = function() {
return $controller('LoginController', {
'$scope': self.$scope,
'$rootScope': self.$rootScope,
'$state': self.$state,
'userService': userServiceMock
});
};
return $httpBackend.whenPOST('http://localhost:9001/api/v1/session/check').respond({
authenticated: true
});
}));
it('should set the page title to "Login"', function() {
self.createController();
$scope.init();
expect($rootScope.pageTitle).toBe('Login');
return expect($scope.auth).toEqual({});
});
return it('should properly authenticate a user', function() {
self.createController();
$scope.init();
$scope.auth = {
username: 'test@test.com',
password: 'mypassword'
};
$scope.login();
self.deferred.resolve({
authenticated: true
});
$scope.$root.$digest();
console.log($state.current.name);
expect($state.current.name).toBe('dashboard');
});
});
})();

我想很简单吧?我的 Controller 是:

myApp.controller('LoginController', [
'$scope', '$rootScope', '$state', 'userService', function($scope, $rootScope, $state, userService) {
$scope.init = function() {
$rootScope.pageTitle = 'Login';
return $scope.auth = {};
};
$scope.login = function() {
return userService.login($scope.auth).then(function(response) {
if (response.authenticated === true) {
return $state.transitionTo('dashboard');
} else {
return console.log('bad password man');
}
});
};
return $scope.init();
}
]);

我在测试中得到的是:

NFO [karma]: Karma v0.12.16 server started at http://localhost:9876/
INFO [launcher]: Starting browser PhantomJS
INFO [PhantomJS 1.9.7 (Mac OS X)]: Connected on socket TRjrAWL8PHdQ-bKqkyzK with id 61166122
LOG: 'HERE!'
PhantomJS 1.9.7 (Mac OS X) - Login Controller:
PhantomJS 1.9.7 (Mac OS X) should set the page title to "Login" PASSED
PhantomJS 1.9.7 (Mac OS X) should properly authenticate a user FAILED
PhantomJS 1.9.7 (Mac OS X): Executed 2 of 2 (1 FAILED) (0.02 secs / 0.018 secs)
PhantomJS 1.9.7 (Mac OS X)
PhantomJS 1.9.7 (Mac OS X) Login Controller should properly authenticate a user FAILED
Error: Unexpected request: GET templates/dashboard.html
No more request expected

发生这种情况的原因是因为状态转换为 dashboard,然后它尝试加载 dashboard.html 模板。我不一定要/需要测试它。我只需要测试它是否达到了正确的状态。我该如何正确设置它?

我正在使用 Angular UI Router而不是内置的 $routeProvider

最佳答案

简短的回答是你需要告诉 $httpBackend 期待请求。如果任何请求被发送但未被 $httpBackend 捕获,Karma 将抛出错误,因为它们都应该在单元测试中被模拟。它可能看起来像……

$httpBackend.expectGET('/templates/dashboard.html');
$scope.login();
$httpBackend.flush();

我说这只是简短的回答,因为这里发生了一些事情,不提及它们会有点损害。首先,您使用 $httpBackend 来捕获身份验证 POST 请求,但是您实际上并没有发送请求,因为您在模拟 userService。你不需要两者都做。您可以删除此代码...

return $httpBackend.whenPOST('http://localhost:9001/api/v1/session/check').respond({
authenticated: true
});

因为该请求实际上不会由您的模拟用户服务发送。不过,该代码可能对您的 userService 的单元测试有用。

我还会使用 beforeEach/afterEach Hook 。当您可以在 beforeEach 函数中调用一次并且它将在每个测试之前运行时,无需在所有测试中调用 self.createController 。如果您不小心,这可能会变得一团糟。

最后,测试 View 更改和设置新页面标题正在突破单元测试的用途限制。理想情况下,您将在集成测试中测试路由和页面更改(如果有的话)。在第二次测试中,您真正要测试的唯一一件事是......

$state.transitionTo('dashboard')

做它应该做的事(将当前的 $state 更新为“dashboard”)。你应该相信这个作品。 UI-router 有自己的测试证明这是有效的。我会努力使您的单元测试尽可能小,并且只单独测试应用程序各个组件的特定行为。所以与其问..

“当我调用 $scope.login() 时,是否会调用 userService 的登录函数并发送 POST 请求并更改状态?”

我只想问...

“当我调用 $scope.login() 时,是否调用了 userService 的登录函数?”

其余的不是您的 Controller 的责任。是否发送请求是 userService 的责任(应该在那里测试),当你调用 $state.transitionTo 时状态是否改变是 ui-router 的范围并且已经在那里测试。将跨越多个组件的高级测试留给集成测试。

关于javascript - 如何使用 ui-router 测试依赖于服务的 AngularJS Controller ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23957368/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com