简体   繁体   中英

Angularjs directive unit test issue

I am trying to fill ng-repeat (home.html) with a directive named 'card' as written below. CardProvider is promise object which is loading content with $http.

Each directive in ng-repeat adding html content with ng-include. And each directive doing some stuff and using getContentUrl function to bring different html according to type.

I am using karma, mocha, chai for unit test and AngularJS v1.2.18.

My problem is, when i created unit test as below. I am having test error as below:

TypeError: undefined is not a function at Scope.scope.getContentUrl (/Users/me/projects/web/src/app.js:161:31)

It seams that i cannot access the each isolated scope of directive inside ng-repeat.

home.html

<ul id="container" ng-controller="CardCtrl">
  <li card index="{{$index}}" type="{{item.in.Collection}}" ng-repeat="item in cards"></li>
</ul>

app.js

angular.module('App', ['ngRoute'])

  .config(function($routeProvider){
    $routeProvider
      .when("/",{
        templateUrl: "view/home.html",
        controller: "CardCtrl",
        resolve: {
          load: function ($route, CardProvider) {
            return CardProvider.load();
          }
        }
      })
      .otherwise({
        redirectTo: "/!"
      });
  })

  .controller('CardCtrl', ['$scope', 'CardProvider', function($scope, CardProvider) {
    $scope.cards = CardProvider.data;
  }])

  .directive('card', ['$window', 'CardProvider', function($window, CardProvider) {
    return {
      scope: {
        index: '@',
        type: '@'
      },

      template: '<div class="card-wrapper" ng-include="getContentUrl()"></div>',
      link: function(scope) {

        // Find which card processing
        scope.card = CardProvider.data[scope.index];

        scope.getContentUrl = function() {
          // When reached last card activate packery library to designate screen
          if (parseInt(scope.index) + 1 == CardProvider.data.length) {
            var container = angular.element('#container');

            // Activate packery
            var packery = new $window.Packery(container[0], {
              itemSelector: '.card',
              gutter: 10
            });
          }

          // If we have a type specifier return it otherwise null
          return scope.type ? 'public/js/directives/' + scope.type + '.html' : '';
        }
      }
    };
  }]);

Karma.conf.js:

module.exports = function(config) {
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '../',

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['mocha','jquery-chai'],

    // list of files / patterns to load in the browser
    files: [
      'public/components/angular/angular.js',
      'public/components/angular-route/angular-route.js',
      'public/components/angular-mocks/angular-mocks.js',
      'src/app.js',
      'test/unit/*.spec.js'
    ],

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['Chrome']
  });
};

Test file unit/cards.spec.js:

var assert = chai.assert,
    expect = chai.expect,
    should = chai.should();

describe('Cards Unit Tests', function() {
  var scope, cardsElement, httpBackend, controller;
  var discussions = [{
    "title": "\"The Incubation Period: Why Stanford’s Startup Culture is Only\"",
    "on": "2014-06-01T17:56:59.301+03:00",
    "tags": [
      "startup"
    ],
    "in": {
      "Collection": "communities",
      "Id": "538ccd41062a2a0fafbae507",
      "Database": ""
    },
    "posts": [
      {
        "on": "2014-06-01T17:56:59.301+03:00",
        "author": {
          "Collection": "profiles",
          "Id": "538cc882062a2a0fafbae4fa",
          "Database": ""
        },
        "content": "The article below is a product of the Harvard Political Review. Review articles and viewpoints expressed are written and edited exclusively by Review undergraduate students.",
        "popularity": 4.7
      }
    ]
  }];
  var cardContent = '<ul id="container" ng-controller="CardCtrl"><li card index="{{$index}}" type="{{item.in.Collection}}" ng-repeat="item in cards"></li></ul>';

  beforeEach(module('App'));

  beforeEach(inject(function($rootScope, $controller, $httpBackend, CardProvider) {
    scope = $rootScope.$new();
    controller = $controller;
    httpBackend = $httpBackend;
    CardProvider.data = discussions;
    //httpBackend.whenGET('http://localhost:8080/explore/discussions').respond(discussions);
  }));

  beforeEach(inject(function($compile, $rootScope) {
    var el = angular.element(cardContent);
    cardsElement = $compile(el)(scope);
    scope.$digest();
  }));

  it('should show load cards to the page', function() {
    expect(cardsElement.find('li').length).to.be.above(0);
  });
});

根据错误消息以及在scope.getContentUrl()唯一用作函数的事实是$window.Packery Packery ,似乎Packery未正确加载。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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