单元测试 - 未知提供者:stateParamsProvider< - stateParams

时间:2016-09-25 12:33:19

标签: angularjs unit-testing ionic-framework karma-jasmine

我正在尝试运行单元测试来检查PhraseListCtrlPhraseService的输出。预期的输出如下:

GET /api/phrase-category/1551742a-5963-4d40-9abb-af7a6fb4ec5d/
HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

[
    {
        "phrase_id": "f40e0e47-6457-463b-a5f9-9dc97bd2d0ce",
        "phrase": "Training {{group}} to develop their {{attribute}} by ensuring they are comfortable with {{factor}}",
        "category": "Coach"
    },
    {
        "phrase_id": "66314a72-07ae-445c-97c0-4f659387bbb2",
        "phrase": "Assisting {{person}} in strength and conditioning work to improve {{factor}}",
        "category": "Coach"
    }
]

但是我一直收到以下错误消息Unknown provider: stateParamsProvider <- stateParams。我该如何解决?

控制器

function PhraseListCtrl($scope, $stateParams, PhraseService, FilterService) {

    $scope.categoryId = $stateParams.categoryId;
    $scope.category = $stateParams.category;

    PhraseService.getPhraseCategory($scope.categoryId).then(function(dataResponse) {
        $scope.phraseCategory = dataResponse.data;

        var replacers = FilterService.getItemFilter();

        $scope.phraseCategory.forEach(function(e){
            Object.keys(replacers).forEach(function(key){
                e['phrase'] = e['phrase'].replace(new RegExp(key, 'g'), replacers[key]);
            })
        })
    })

}

服务

function PhraseService($http) {

    this.getPhraseCategory = function (categoryId) {

        return $http({
            method: 'GET',
            url: server + '/api/phrase-category/' + categoryId,
        });

    }

}

function FilterService() {

    this.getItemFilter = function () {

        var replacers = {
            '{{group}}' : '<div class="button button-small button-outline button-positive button-side-padding">group</div>',
            '{{attribute}}' : '<div class="button button-small button-outline button-assertive button-side-padding">attribute</div>',
            '{{factor}}' : '<div class="button button-small button-outline button-assertive button-side-padding">factor</div>',
            '{{person}}' : '<div class="button button-small button-outline button-positive button-side-padding">person</div>'
        }

        return replacers;

    }

}

单元测试

    describe('PhraseListCtrl', function() {

var response;
response = {
  status: 200,
  data: [{
    "phrase_id": "1551742a-5963-4d40-9abb-af7a6fb4ec5d",
    "phrase": "Training {{group}} to develop their {{attribute}} by ensuring they are comfortable with {{factor}}",
    "category": "Coach"
  }]
};

var stateParams;

// Injecting the modules that would then be used in the tests

beforeEach(module('dingocv.services'));
beforeEach(module('dingocv.controllers'));

beforeEach(inject(function($controller, $rootScope, _PhraseService_, _FilterService_, stateParams) {
  $scope = $rootScope.$new();
  PhraseService = _PhraseService_;
  FilterService = _FilterService_;
  stateParams = {
    categoryId: "1551742a-5963-4d40-9abb-af7a6fb4ec5d",
    category: "Coach"
  }

  // Creating a spy for this method so that it doesn't call the original Service method.

  spyOn(PhraseService, 'getPhraseCategory').and.callFake(function(){
    return{
      then: function(successCallback){
        successCallback(response);
      }
    }
  });

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

describe('#initialisation', function() {
      it('should initialise the controller\'s scope with a list of phrases by category', function(){
          expect(PhraseService.getPhraseCategory).toHaveBeenCalled();
          expect($scope.phraseCategory).toBeDefined();
          expect($scope.phraseCategory.length).toEqual(1);
  });

});

错误输出

Chrome 53.0.2785 (Windows 10 0.0.0) PhraseListCtrl #initialisation should initialise the controller's scope with a list of phrases by category FAILED
        Error: [$injector:unpr] Unknown provider: stateParamsProvider <- stateParams
        http://errors.angularjs.org/1.5.3/$injector/unpr?p0=stateParamsProvider%20%3C-%20stateParams
            at D:/myapp-mobile/www/lib/ionic/js/ionic.bundle.js:13438:12
            at D:/myapp-mobile/www/lib/ionic/js/ionic.bundle.js:17788:19
            at Object.getService [as get] (D:/myapp-mobile/www/lib/ionic/js/ionic.bundle.js:17941:39)
            at D:/myapp-mobile/www/lib/ionic/js/ionic.bundle.js:17793:45
            at getService (D:/myapp-mobile/www/lib/ionic/js/ionic.bundle.js:17941:39)
            at injectionArgs (D:/myapp-mobile/www/lib/ionic/js/ionic.bundle.js:17965:58)
            at Object.invoke (D:/myapp-mobile/www/lib/ionic/js/ionic.bundle.js:17987:18)
            at Object.workFn (D:/myapp-mobile/www/lib/angular-mocks/angular-mocks.js:3085:20)
        Error: Declaration Location
            at window.inject.angular.mock.inject (D:/myapp-mobile/www/lib/angular-mocks/angular-mocks.js:3047:25)
            at Suite.<anonymous> (unit-tests/phrase-list.controller.tests.js:20:16)
            at unit-tests/phrase-list.controller.tests.js:1:3
        ReferenceError: PhraseService is not defined
            at Object.<anonymous> (unit-tests/phrase-list.controller.tests.js:46:22)
PhantomJS 2.1.1 (Windows 8 0.0.0): Executed 2 of 2 (1 FAILED) (0.132 secs / 0.016 secs)
Chrome 53.0.2785 (Windows 10 0.0.0): Executed 2 of 2 (1 FAILED) (0.474 secs / 0.147 secs)
TOTAL: 2 FAILED, 2 SUCCESS

1 个答案:

答案 0 :(得分:0)

这是依赖注入问题。这修好了它:

describe('PhraseListCtrl', function () {

  var $controller, $stateParams, $PhraseService, $FilterService;

  $stateParams = {
    categoryId: "1551742a-5963-4d40-9abb-af7a6fb4ec5d",
    category: "Coach"
  };

  var response = {
    status: 200,
    data: [{
      "phrase_id": "1551742a-5963-4d40-9abb-af7a6fb4ec5d",
      "phrase": "Training {{group}} to develop their {{attribute}} by ensuring they are comfortable with {{factor}}",
      "category": "Coach"
    }]
  };

  beforeEach(module('dingocv.services'));
  beforeEach(module('dingocv.controllers'));

  beforeEach(inject(function (_$controller_, _PhraseService_, _FilterService_) {
    $controller = _$controller_;
    $PhraseService = _PhraseService_;
    $FilterService = _FilterService_;

    spyOn(_PhraseService_, 'getPhraseCategory').and.callFake(function(){
      return{
        then: function(successCallback){
          successCallback(response);
        }
      }
    });
  }));

  describe('$scope.correct', function() {

    var $scope, controller;

    beforeEach(function () {
      $scope = {};
      controller = $controller('PhraseListCtrl', {$scope: $scope, $stateParams: $stateParams, PhraseService: $PhraseService, FilterService: $FilterService});
    });

    it('gary is correct', function () {
      expect($scope.gary()).toEqual('correct');
    });

    it('should initialise the controller\'s scope with a list of phrases by category', function(){
      expect($PhraseService.getPhraseCategory).toHaveBeenCalled();
      expect($scope.phraseCategory).toBeDefined();
      expect($scope.phraseCategory.length).toEqual(1);
      expect($scope.phraseCategory[0].id).toEqual(response.data[0].id);
      expect($scope.phraseCategory[0].category).toEqual(response.data[0].category);
    });

  });

});