javascript - 在 AngularJS 中模拟 Controller 单元测试的依赖服务

标签 javascript angularjs unit-testing karma-jasmine

我在对 Ionic 应用程序进行单元测试时遇到问题。我见过类似的问题,但没有解决我的问题。

基本上,这是我的controller.js

angular.module('starter.controllers')
.controller('myController', function($scope, myService) {

    $scope.test = function() {
        return myService.getTestVariable();
    };

});

这是我的service.js

angular.module('starter.services')
.factory('myService', function() {

    var self = this;
    self.testVariable = true;

    return {
        getTestVariable : function() {
            return self.testVariable;
        }
    };
});

模块在 app.js 文件中创建:

angular.module('starter', ['starter.controllers', 'starter.services']);           
angular.module('starter.services', []);
angular.module('starter.controllers', []);

现在,我想测试 Controller 并使用服务的模拟版本,因此我设置了如下测试:

describe('Controller: myController', function() {
    var scope, controller, serviceMock;

    beforeEach(function() {
        module('starter');
    });

    beforeEach(function () {
        serviceMock= {
            getTestVariable : function() {return true;}
        };

        module(function ($provide) {
            $provide.value('myService', serviceMock);
        });
    });

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

    it('should work as expected', function(){
        spyOn(serviceMock, 'getTestVariable').and.callThrough();
        scope.test();
        expect(serviceMock.getTestVariable).toHaveBeenCalled();
    });
});

但是,当我尝试运行测试时,它会打印错误:

TypeError: 'undefined' is not a function (evaluating 'myService.getTestVariable()')
    at <dir>/controller.js:5

为什么会发生这种情况?

最佳答案

我在代码中没有看到任何问题,只需进行模块初始化 angular.module('starter.services', []); angular.module('starter.controllers', []); 在使用之前。

请参阅下面的示例。您提供的相同代码可以完美运行。

angular.module('starter.controllers', []);
angular.module('starter.controllers')
  .controller('myController', function($scope, myService) {

    $scope.test = function() {
      return myService.getTestVariable();
    };

  });

angular.module('starter.services', []);
angular.module('starter.services')
  .factory('myService', function() {

    var self = this;
    self.testVariable = true;

    return {
      getTestVariable: function() {
        return self.testVariable;
      }
    };
  });

angular.module('starter', ['starter.controllers', 'starter.services']);

describe('Controller: myController', function() {
  var scope, controller, serviceMock;

  beforeEach(function() {
    module('starter');
  });

  beforeEach(function() {
    serviceMock = {
      getTestVariable: function() {
        return true;
      }
    };

    module(function($provide) {
      $provide.value('myService', serviceMock);
    });
  });

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

  it('should work as expected', function() {
    spyOn(serviceMock, 'getTestVariable').and.callThrough();
    scope.test();
    expect(serviceMock.getTestVariable).toHaveBeenCalled();
  });
});
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.2.1/jasmine.min.css">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.2.1/jasmine.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.2.1/jasmine-html.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.2.1/boot.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular-mocks.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.min.js"></script>

关于javascript - 在 AngularJS 中模拟 Controller 单元测试的依赖服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30624206/

相关文章:

javascript - 从 JSON 中提取特定值

javascript - 在 foreach 循环中使用 $root 值设置 href

javascript - 选择路径,根据图例鼠标悬停更改不透明度

javascript - 使用 ng-options AngularJS 中的值选择下拉列表

typescript - 在对 LitElement 组件进行单元测试时如何正确 stub 元素?

ruby-on-rails - 测试和建立连接

java - org.junit.Assert 本身的 JUnit NoClassDefFoundError

javascript - 如何匹配但排除以下 JavaScript 正则表达式中的等号?

javascript - 我如何在 Firebase Angularjs 中使用 $id 作为数字或新变量?

AngularJS 指令 transclude 部分绑定(bind)