使用服务测试控制器

Testing controllers with services

我是 angular 和单元测试的新手。

我有一个应用程序模块 MyApp 包括所有其他模块都需要的基本服务和服务,例如日志记录服务 loggingService

我还有一个模块用于处理关于地图和地理定位的所有内容,名为 MapModule,我还有一个用于应用程序逻辑的主模块,名为 MainModule

MainModule 包含一个我想测试的控制器:messageSendCtrl 控制器有一些依赖性,比如来自 MapModule.

的服务

并且:MainModuleMapModule 依赖于 MyApp,因为到处都需要 loggingService

代码看起来像这样(伪代码):

MyApp

var MyApp = angular
        .module('MyApp', ['ngRoute','MainModule','MapModule']);

MyApp.service('loggingService', function (one, two) {
   [..] /*logging data somewhere for debugging application*/
});

主模块

var MainModule = angular
        .module('MainModule', []); 
MainModule.controller('messageSendCtrl', 
    function($scope,$http, $location, locationService, loggingService) {
[...]
});

MapModule

var MapModule = angular
        .module('MapModule', ['uiGmapgoogle-maps']);
MapModule.service('locationService', function (loggingService) {
[...]

我喜欢测试的是MainModule中的messageSendCtrl。 (可能)我能够将定位服务注入测试环境。但是注入 locationService 没有成功。

可能是因为 locationService 也使用了 loggingService.

运行 测试结果在

Error: [$injector:unpr] Unknown provider: loggingServiceProvider <- loggingService <- locationService

我的测试是这样的:

describe('saving a document', function() {

  beforeEach(module('MainModule'));
  beforeEach(module('MyApp'));
  beforeEach(module('MapModule'));

  describe ('messageSendCtrl', function () {
    var scope,ctrl,locationService,loggingService; 

    beforeEach(inject(function($rootScope, $controller,_locationService_,_loggingService_) {
        scope = $rootScope.$new();
        ctrl = $controller('messageSendCtrl', 
                    {$scope: scope,
                     locationService: _locationService_,
                     loggingService : _loggingService_ });
    }));


      it('should actual not saved', function(){
        expect(scope.result).to.equal('unsaved');
    }); 
  })
});

那么我可以解决谁的依赖关系呢?还是我的应用程序存在设计问题?

事情有很多,让我们一一检查:

  1. 在你的测试中,你不需要加载你所有的模块,只加载你想要测试的那个模块,你的 ctrl 在你的 MainModule 中,所以只使用 beforeEach(module('MainModule'));
  2. 每个模块都应声明其依赖项,因此您的 MainModule 声明应如下所示:var MainModule = angular.module('MainModule', ['MyApp']); 因为 MainModule 中的一个控制器依赖于另一个模块 (MyApp) 中的服务
  3. 测试一个模块是否只做一件事会更容易,因此如果您有日志记录服务,请为此创建一个日志记录服务模块,并将该模块包含在您要使用日志记录的位置。 所以不要让模块负责几个不同的事情,因为如果其他模块需要日志记录,该模块将获得您的 "godmodule" 包含的所有其他服务,这使得测试和查找错误变得困难。