我对AngularJS并不陌生,正在尝试学习一些最佳实践。我的工作正常,但想开始向我的模块和 Controller 添加一些单元测试。我要解决的第一个是AuthModule。

我有一个AuthModule。该模块注册一个名为“AuthModule”的工厂,并公开诸如“setAuthenticatedUser”之类的内容以及诸如“isLoggedIn”和“currentUser”之类的字段。我认为这是AngularJS应用程序中的一种相当普遍的模式,在具体实现细节上有一些变化。

authModule.factory(
'AuthModule',
函数(APIService,$ rootScope){

  var _currentUser = null;
  var _isLoggedIn = false;

  return {
    'setAuthenticatedUser' : function(currentUser) {

      _currentUser = currentUser;
      _isLoggedIn = currentUser == null ? false : true;

      $rootScope.$broadcast('event:authenticatedUserChanged',
          _currentUser);

      if (_isLoggedIn == false) {
        $rootScope.$broadcast('event:loginRequired')
      }

      $rootScope.authenticatedUser = _currentUser;
      $rootScope.isLoggedIn = _isLoggedIn;

    },
    'isLoggedIn' : _isLoggedIn,
    'currentUser' : _currentUser
  }
});

该模块还执行其他一些操作,例如为事件“loginRequired”注册处理程序,以将人员发送回主屏幕。这些事件由AuthModule工厂引发。
authModule.run(function($rootScope, $log, $location) {
  $rootScope.$on("event:loginRequired", function(event, data) {
    $log.info("sending him home. Login is required");
    $location.path("/");
  });
});

最后,该模块有一个运行块,它将使用API​​服务,我必须确定后端当前登录的用户。
 authModule.run(
     function(APIService, $log, AuthModule) {
       APIService.keepAlive().then(function(currentUser) {
         AuthModule.setAuthenticatedUser(currentUser.user);
       }, function(response) {
         AuthModule.setAuthenticatedUser(null);
       });
     });

这是我的一些问题:

我的问题是您如何为此设置测试?我认为我需要模拟出APIService吗?我很难过,因为我不断收到对/ keepalive函数的意外POST请求(在APIService.keepAlive()中调用)?

有什么方法可以使用$ httpBackend来将正确的响应返回到实际的KeepAlive调用?这样可以避免我不得不模拟API服务吗?

我是否应该将.run()块拉出以从AuthModule中获取当前登录的用户并将其放入主应用程序中?似乎无论我将run()块放在哪里,似乎都无法在加载模块之前初始化$ httpbackend?

AuthModule是否应该完全是它自己的模块?还是应该只使用主应用程序模块并在那里注册工厂?

最佳答案

运行块是Angular中最接近main方法的。运行块是启动应用程序所需运行的代码。在配置完所有服务并创建了注入(inject)器后,将执行该命令。运行块通常包含难以进行单元测试的代码,因此,应在隔离的模块中声明它们,以便可以在单元测试中将其忽略。 angularjs docs

我建议您看看authentication service,使用服务是一种方法。

希望这会有所帮助...祝你好运

10-05 20:50