javascript - 使模块在 jasmine 通过 Resharper 测试的 Controller 中可用

标签 javascript angularjs jasmine resharper

我可以使用 Resharper 9.2 通过 PhantomJs 使用 jasmine 成功测试 Controller 。作为测试运行者。

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

这有效:如果我不指定它所依赖的模块,我可以为 Controller 运行测试:

Controller :

    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 = {}));

规范文件看起来像这样

    ///<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');
        });

    });
});

真正的 Controller 使用angular ui bootstrap“ui.bootstrap”。如果我将 Controller 更改为下一个示例, Controller 将在页面上工作,但是当我尝试测试它时出现错误

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)

依赖于 Bootstrap 的 Controller

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 = {}));

**编辑 1 ** 我试过了

beforeEach(
    function () {
        module("ui.bootstrap");
        module("moduleName");
    }
    );

但有同样的错误。

编辑 2 我用

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

AngularJS v1.2.24

编辑 3 我不想测试 $uibModal,而是模拟它

最佳答案

我知道两种模拟服务的策略,具有多种语法变体,就像 Angular 中的所有内容一样......您可以简单地将对象文字添加到 Controller 声明中,或者您可以创建自己的服务并使用 $ vendor :

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

var currentAuth;

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

    controller = $controller('TestableCtrl', {'$scope': $scope, 'currentAuth': currentAuth });
}));

在这种情况下,“currentAuth”是一项服务,可提供应用程序中的当前登录用户。

这仅在您不需要在对象中定义的函数中注入(inject)任何服务时才有效。这相当于创建一个值(value)服务并将其注入(inject)到模块中。如果模拟服务中的方法本身需要任何服务,您将必须创建一个工厂或服务,将此服务添加到模块,然后像任何其他自定义服务一样注入(inject)它。请参阅我用来模拟 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: {}
      });
    });

  });

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

使用哪一个取决于您要测试什么以及您需要多深地模仿原始服务行为。在您使用 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();
        });

    });
});

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

关于javascript - 使模块在 jasmine 通过 Resharper 测试的 Controller 中可用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38973359/

相关文章:

javascript - 用于测试函数调用失败的 Jasmine 测试

javascript - 如何用逗号分隔 $ ('ul li' ).text

javascript - 即使在添加 CORS 配置后,S3 也会出现 CORS 错误

angularjs - Angular 2 测试 - 组件状态在测试之间持续存在(即不重置)

javascript - 动态注入(inject)指令

javascript - 如何在页面加载后执行功能在angularjs中完成

JavaScript innerHTML 导致 css 在 <button> 上消失

javascript - Node typescript 缺少构造签名(新缓冲区)

javascript - 多个异步测试 Jasmine

javascript - 在 Jquery 中工作时如何使用 Jasmine 测试文本颜色?