【问题标题】:Mock factory on controller test控制器测试的模拟工厂
【发布时间】:2016-08-20 17:15:11
【问题描述】:

这是我的控制器

angular
.module('studentsApp')
.controller('StudentsController', StudentsController);

function StudentsController($scope, StudentsFactory) {
    $scope.students = [];
    $scope.specificStudent= {};

    var getStudents = function() {
        StudentsFactory.getStudents().then(function(response) {
            if($scope.students.length > 0){
                $scope.students = [];
            }
            $scope.students.push(response.data);
        });
    };
}

这是我的工厂

angular.module('studentsApp')
.factory('StudentsFactory', function($http) {
  var base_url = 'http://localhost:3000';
  var studentsURI = '/students';
  var studentURI = '/student';
  var config = {
    headers: {
      'Content-Type': 'application/json'
    }
  };

  return {
    getStudents: function() {
      return $http.get(base_url + studentsURI);
    }
  };
});

我正在尝试对控制器进行单元测试

describe('Controller: Students', function() {
  var StudentsController, scope, StudentsFactory;
  beforeEach(function() {
    module('studentsApp');
    inject(function($rootScope, $controller, $httpBackend, $injector) {
      scope = $rootScope.$new();
      httpBackend = $injector.get('$httpBackend');
      StudentsFactory = $injector.get('StudentsFactory');

      StudentsController = $controller('StudentsController', {
        $scope : scope,
        'StudentsFactory' : StudentsFactory
      });

      students = [{
        name: 'Pedro',
        age: 10
      }, {
        name: 'João',
        age: 11
      }, {
        name: 'Thiago',
        age: 9
      }];

      spyOn(StudentsFactory, 'getStudents').and.returnValue(students);
    });
  });

  it('Should get all students', function() {
    scope.students = [];

    StudentsController.getStudents();
    $scope.$apply();
    expect(scope.students.length).toBe(3);
  });
});

问题是,当我运行测试时,显示以下消息:

undefined 不是构造函数(评估 'StudentsController.getStudents()')

我查看了整个互联网试图找到一个可以帮助我的教程,但我没有找到任何东西,有人可以在这里帮助我吗?

【问题讨论】:

    标签: javascript angularjs unit-testing controller factory


    【解决方案1】:

    这与函数 getStudent() 是私有的(由 var 声明)这一事实有关。因此您的测试无法访问它。您必须将其附加到 $scope 或 this 才能对其进行测试。 我一般在控制器中使用这个:

    var $this = this;
    $this.getStudents = function() {
        ...
    };
    

    【讨论】:

    【解决方案2】:

    没有StudentsController.getStudents 方法。应该是

    this.getStudents = function () { ... };
    

    Mocked StudentsFactory.getStudents 返回一个普通对象,而它应该返回一个 Promise。

    $controller 不应作为本地依赖提供真正的StudentsFactory 服务(默认情况下已提供):

      var mockedStudentsFactory = {
        getStudents: jasmine.createSpy().and.returnValue($q.resolve(students))
      };
    
      StudentsController = $controller('StudentsController', {
        $scope : scope,
        StudentsFactory : mockedStudentsFactory
      });
    

    【讨论】:

    • 我试过了,但是,它并没有将学生的价值添加到 scope.students.. 另一件事是。我没用$q,我用的是$http,有问题吗?
    • $http 返回 $q 承诺,响应可以用已解决的 $q 承诺模拟。 students 在您的情况下是一个数组,它应该是一个具有 data 属性的对象。此时它应该工作或抛出一个有意义的错误。如果这仍然对您不起作用,请发布一个小提琴/plunk,以显示您的情况出了什么问题。
    • 谢谢,但是还不行,看起来是在调用promise,但是没有把数组的值放在scope.students中,我创建了一个小提琴,这样你就可以看到代码更好:jsfiddle.net/z9k3c35c你能帮帮我吗?
    • 您发布的小提琴无法使用。目前尚不清楚您的情况出了什么问题,此时它应该可以工作。运行规范并显示错误的工作小提琴会有所帮助。请发布您遇到的确切错误(带有调用堆栈)并进行所有更正。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-10
    • 2015-04-07
    相关资源
    最近更新 更多