如何模拟在module.run Angular应用程序中执行的http调用?

时间:2013-11-05 10:05:31

标签: unit-testing angularjs mocking

我正在尝试运行以下代码(其中fusseApp是一个angularModule):

fusseApp.run(function(URI, $http){

  $http.get('/check/userLogged').then(function(response){
            console.log(response);
  });

PS:实际上我的http调用是在工厂执行的,在这里我们只需要调用这个工厂

angularModule被模拟:

angular.module('fusseApp.mainMocks', ['fusseApp', 'fusseApp.loginMocks', 'ngMockE2E', 'ngResource'])
    .run(function($httpBackend, $http) {

...

$httpBackend.whenGET('/check/userLogged').respond(200,response);

我的问题是在初始化mock模块之前执行了fusseApp.run。所以我有一个错误:

未捕获错误:意外请求:GET / check / userLogged 不再需要预期

这个问题似乎已经在茉莉花单元测试中提出,但我找不到解决方案。在事件告诉我应用程序何时完全初始化后,是否可以运行我的$http调用?

我需要在屏幕上显示任何数据之前检查用户是否已通过身份验证。

1 个答案:

答案 0 :(得分:0)

也许这可以帮助...

如果你在代码中设置.run(),它是boostrap进程的一部分,那么总是会执行{p> ng-app="",你不能停止编译&链接过程,但有很多方法可以阻止在用户未登录时呈现视图:

A)手动角度boostraping(不是那么有趣但可行)可以在认证完成后完成,使用jQuery $ .ajax或其他lib,因为$ http服务在NG外面的图片外。

B)但是在.run()您可以访问$rootScope和所有NG服务,因此您可以监听$stateChangeStart并在侦听器内执行身份验证。

这或多或少是NG身份验证的最佳实践,每次用户更改状态时,此侦听器都会一直检查(这很好,以便您可以捕获会话到期),在我的代码中(我在各种prod中使用)项目)我这样做:

$rootScope.$on("$stateChangeStart", function(event, toState, toParams, fromState, fromParams) {
    if (!AuthService.isAuthenticated()) {
        $state.transitionTo("login"); // redirect to login page
        event.preventDefault();
    }
});

AuthService只是一个简单的服务,如果用户通过身份验证,则返回truefalse。 根据我的经验,隐藏未授权用户的视图和重定向的最佳解决方案是捕获状态更改过程,就像我之前显示的那样。 因为你可以装饰状态,所以可以在toState参数中访问这些属性(至少在ui-router中)所以可以做各种奇特的事情,比如捕获用户角色等......