在茉莉花通过Resharper测试的控制器中提供模块

Mat*_*s F 14 javascript resharper jasmine angularjs

我可以使用Resharper 9.2通过PhantomJs使用jasmine成功测试控制器.作为一名Testrunner.

我按照https://blogs.endjin.com/2014/09/unit-testing-angularjs-with-visual-studio-resharper-and-teamcity/上的说明设置Resharper.

这工作:如果我不指定它所依赖的模块,我可以为控制器运行测试:

控制器:

    var moduleName;
(function (moduleName) {
    'use strict';
    var testableController = (function () {
        function testableController($scope) {
            var _this = this;
            this.$scope = $scope;

            $scope.title = "Welcome";
        }
        testableController.className = 'testableController';
        return testableController;
    }());
    moduleName.testableController = testableController;
})(moduleName || (moduleName = {}));
Run Code Online (Sandbox Code Playgroud)

spec文件看起来像这样

    ///<reference path="~/Scripts/jasmine/jasmine.js"/>
///<reference path="~/Scripts/jasmine/angular.js"/>
///<reference path="~/Scripts/jasmine/angular-mocks.js"/>
///<reference path="~/Scripts/angular-ui/ui-bootstrap.min.js" />
///<reference path="~/Scripts/jasmine/controllers.js"/>
///<reference path="~/Scripts/App/Controllers/testableController.js" />
///<reference path="~/Scripts/App/AppJasmine.js" />
describe("Controllers", function() {

    beforeEach(module("moduleName"));

    describe("Jasmine  testableController", function () {

        var scope,
            controller;

        beforeEach(inject(function ($rootScope, $controller) {
            scope = $rootScope.$new();
            controller = $controller('testableController', { $scope: scope });
        }));

        it('should set the page title as "Welcome"', function () {
            expect(scope.title).toBe('Welcome');
        });

    });
});
Run Code Online (Sandbox Code Playgroud)

真正的控制器使用角度ui bootstrap"ui.bootstrap".如果我将控制器更改为下一个样本,则控制器在页面上工作但是当我尝试测试它时会出现错误

Error: [$injector:unpr] Unknown provider: $templateRequestProvider <- $templateRequest <- $uibModal
http://errors.angularjs.org/1.2.24/$injector/unpr?p0=%24templateRequestProvider%20%3C-%20%24templateRequest%20%3C-%20%24uibModal in http://localhost:61032/referenceFile?path=~/webui/trunk/Netvacation.Pegasus.WebUI/Scripts/jasmine/angular.js (line 3802)
Run Code Online (Sandbox Code Playgroud)

控制器依赖于Bootstrap

angular.module('moduleName', ['ui.bootstrap']);
var moduleName;
(function (moduleName) {
    'use strict';
    var testableController = (function () {
        function testableController($scope, $uibModal) {
            var _this = this;
            this.$scope = $scope;
            this.$uibModal = $uibModal;
            $scope.title = "Welcome";
        }
        testableController.className = 'testableController';
        return testableController;
    }());
    moduleName.testableController = testableController;
})(moduleName || (moduleName = {}));
Run Code Online (Sandbox Code Playgroud)

**编辑1**我试过了

beforeEach(
    function () {
        module("ui.bootstrap");
        module("moduleName");
    }
    );
Run Code Online (Sandbox Code Playgroud)

但有同样的错误.

编辑2 我用

http://angular-ui.github.io/bootstrap/ 版本:1.3.3 - 2016-05-22

AngularJS v1.2.24

编辑3 我不想测试$ uibModal,但是嘲笑它

Jua*_*uez 1

我知道两种模拟服务的策略,具有多种语法变体,就像 Angular 中的一切一样......您可以简单地将对象文字添加到控制器声明中,也可以创建自己的服务并使用 $provider 将它们添加到模块中:

如果服务只是某些数据层或 API 的包装器,您可以使用文字对象模拟其功能,并在控制器构造函数中注入(如果正确),按照示例语法,可以像这样完成:

var currentAuth;

beforeEach(inject(function ($rootScope, $controller) {
    scope = $rootScope.$new();
    currentAuth = {uid: 1, name: juan, getFriends: function() { ... }};

    controller = $controller('TestableCtrl', {'$scope': $scope, 'currentAuth': currentAuth });
}));
Run Code Online (Sandbox Code Playgroud)

在本例中,“currentAuth”是提供应用程序中当前登录用户的服务。

仅当您不需要在对象中定义的函数中注入任何服务时,这才有效。这相当于创建一个价值服务并将其注入到模块中。如果模拟服务内的方法本身需要任何服务,您将必须创建一个工厂或服务,将此服务添加到模块中,然后像任何其他自定义服务一样注入它。请参阅我用来模拟 AngularFire 身份验证服务的示例:

 var $controller, $rootScope, $scope, $location, Auth;

  beforeEach(function(){
    module('planner.login');

    module(function($provide){

      $provide.factory('Auth', function($q){
        return {
          $signInWithEmailAndPassword: function(email, pass) {
            return $q.reject({error: 'ERROR'});
          }
        };
      });

      return null;
    });

  });

  beforeEach(function(){

    inject(function($controller, $rootScope, _Auth_) {
      $scope = $rootScope.$new();
      Auth = _Auth_;

      $controller("TestableCtrl", {
        $scope: $scope,
        Auth: Auth,
        $stateParams: {}
      });
    });

  });
Run Code Online (Sandbox Code Playgroud)

在此示例中,我正在创建一个新工厂,它使用 $q 服务返回一个角度承诺(这不需要在 Chrome 上进行测试,但 PhantomJS 没有 Promise 规范)。请注意,为此您需要两个 beforeEach,一个用于将提供程序添加到模块,另一个用于将提供程序注入到控制器中。

使用哪一种取决于您想要测试什么以及您需要模仿原始服务行为的深度。在使用 uibmodal 的情况下,您可能需要在某个时刻调用“.open”并监视已调用的对象,但您只需要创建一个具有该属性的对象并为此监视该对象属性。所以第一种方法应该足够了。

所以你的代码应该是这样的:

describe("Controllers", function() {

    beforeEach(module("moduleName"));

    describe("Jasmine  testableController", function () {

        var scope,
            controller,
            uibModal;

        beforeEach(inject(function ($rootScope, $controller) {
            scope = $rootScope.$new();
            uibModal = { open: function() { return 'Whatever'; } }
            controller = $controller('testableController', { $scope: scope, $uibModal: uibModal });
        }));

        it('should set the page title as "Welcome"', function () {
            expect(scope.title).toBe('Welcome');
            // you will probably do something like this at some point to verify 
            // that the modal gets opened on click or following any other action:
            // var spy = spyOn(uibModal, 'open');
            // expect(spy).toHaveBeenCalled();
        });

    });
});
Run Code Online (Sandbox Code Playgroud)

我希望它有帮助,如果有不清楚的地方请告诉我,我也在学习如何测试 AngularJS 应用程序,并且很想知道这是否对 AngularUI 有帮助。