简体   繁体   English

Jasmine 测试:$scopeProvider <- $scope <-> DetailController

[英]Jasmine test: $scopeProvider <- $scope <- > DetailController

I am new to AngularJS.我是 AngularJS 的新手。 I have created the following component that contains a template and an associated controller.我创建了以下包含模板和关联控制器的组件。

angular.
module('beerDetail').
controller('BeerDetailController',  ['BeerSelection', '$scope', '$rootScope',
  function BeerDetailController(BeerSelection, $scope, $rootScope) {

    let beerSelected = BeerSelection.getBeerSelected();

    $scope.ok = () => { $rootScope.modalInstance.close() };
    $scope.beer = beerSelected;
    $scope.foodPairings = beerSelected.food_pairing.join(", ");

    this.getFormattedIngredients = (ingredients) => {...};

    this.getFormattedMethod = (method) => {...};

    $scope.allIngredients = this.getFormattedIngredients(beerSelected.ingredients);
    $scope.method = this.getFormattedMethod(beerSelected.method);
  }
]).
component('beerDetail', {
  templateUrl: '/components/beer-detail/beer-detail.template.html',
  controller: 'BeerDetailController',
});

I would like to test the controller, I have created the following test that check whether the beer passed into the scope is the one provided by calling:我想测试控制器,我创建了以下测试来检查传入范围的啤酒是否是通过调用提供的啤酒:

describe('BeerDetailController', function() {

  beforeEach(module('beerDetail'));

  let ctrl;
  let $controller;
  let scope;
  let rootScope;
  let createController;
  let beerSelection;
  let beerSelected = {
    "id": 192,
    "name": "Punk IPA 2007 - 2010",
  };

  beforeEach(inject(function ($controller, $rootScope) {
    scope = $rootScope.$new();
    createController = function () {
      ctrl = $controller('BeerDetailController',
        {'BeerSelection': beerSelection},
        {'$scope': scope},
        {'$rootScope': rootScope}
      );
      spyOn('BeerSelection', 'getBeerSelected').and.returnValues(beerSelected);
    };
  }));

  it('returns the selected beer', function() {

    createController();
    expect(ctrl).toBeDefined();
    expect(scope.beer).toEqual(beerSelected);
    });
  });

I do get the following error however:但是,我确实收到以下错误:

Error: [$injector:unpr] Unknown provider: $scopeProvider <- $scope <- BeerDetailController错误:[$injector:unpr] 未知提供者:$scopeProvider <- $scope <- BeerDetailController

Where might the problem may be?问题可能出在哪里?

When instantiating a controller, the locals are provided as a single object:实例化控制器时,局部变量作为单个对象提供:

//ERRONEOUS
createController = function () {
  ctrl = $controller('BeerDetailController',
    {'BeerSelection': beerSelection},
    {'$scope': scope},
    {'$rootScope': rootScope}
  );

//CORRECT
createController = function () {
  let locals = {
    'BeerSelection': beerSelection,
    '$scope': scope,
    '$rootScope': rootScope
  };
  ctrl = $controller('BeerDetailController', locals);
};

For more information, see AngularJS $controller Service API Reference有关更多信息,请参阅AngularJS $controller 服务 API 参考

For the line对于线

createController = function () {
  ctrl = $controller('BeerDetailController',....

You should fetch the component controller您应该获取组件控制器

//1. inject _$componentController_
//2. var ctrl = _$componentController_('beerDetail', null, bindings);
 it('returns the selected beer', function() {
    expect(ctrl).toBeDefined();
 }); 

Refer to: https://docs.angularjs.org/guide/component#unit-testing-component-controllers参考: https : //docs.angularjs.org/guide/component#unit-testing-component-controllers

As suggested @georgeawg you have to mention all locals in single object to $controller methods 2nd parameter.正如所建议的@georgeawg,您必须在$controller方法的第二个参数中提及单个对象中的所有本地人。 But that would not solved whole issue.但这并不能解决整个问题。

Ideally you should be only mocking injectable like here you have to make BeerSelection .理想情况下,您应该只BeerSelection可注射,就像这里您必须制作BeerSelection That means here you have to mock getBeerSelected method as it has been used by controller directly.这意味着在这里您必须模拟getBeerSelected方法,因为它已被控制器直接使用。

let locals = {
    'BeerSelection': beerSelection,
    '$scope': scope,
    '$rootScope': rootScope
};

And then you have to mock BeerSelection service correctly as below然后你必须正确模拟BeerSelection服务,如下所示

let beerSelected = {
    "id": 192,
    "name": "Punk IPA 2007 - 2010",
};

//BeerSelection service mocking
let beerSelection = {
    //mocked getBeerSelected method
    getBeerSelected: function() {
      return beerSelected;
    }
};

Plunker Demo Plunker 演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM