Karma + PhantomJS TypeError:undefined不是对象(评估scope.jackpot)

时间:2016-04-19 01:34:59

标签: javascript angularjs unit-testing phantomjs karma-jasmine

我仍然是单元测试的新手,说实话,没有任何我甚至可以考虑测试的东西,但除非我至少有一个测试用例,否则我无法构建我的应用程序,所以我试图制作在控制器中最小的代码块上,我可以使用最简单的测试用例,而且它似乎不起作用。

我认为这是我的测试用例中的一个错误,而不是我控制器的代码本身,因为当我在浏览器中使用grunt serve查看我的应用时,控制台显示没有错误。

这是它给我的错误:

PhantomJS 2.1.1 (Linux 0.0.0) Controller: MainCtrl should attach a list of jackpot to the scope FAILED
/home/elli0t/Documents/Yeoman Projects/monopoly/app/bower_components/angular/angular.js:3746:53
forEach@[native code]
forEach@/home/elli0t/Documents/Yeoman Projects/monopoly/app/bower_components/angular/angular.js:323:18
loadModules@/home/elli0t/Documents/Yeoman Projects/monopoly/app/bower_components/angular/angular.js:3711:12
createInjector@/home/elli0t/Documents/Yeoman Projects/monopoly/app/bower_components/angular/angular.js:3651:22
workFn@/home/elli0t/Documents/Yeoman Projects/monopoly/app/bower_components/angular-mocks/angular-mocks.js:2138:60
TypeError: undefined is not an object (evaluating 'scope.jackpot') in /home/elli0t/Documents/Yeoman Projects/monopoly/test/spec/controllers/main.js (line 20)
/home/elli0t/Documents/Yeoman Projects/monopoly/test/spec/controllers/main.js:20:17
PhantomJS 2.1.1 (Linux 0.0.0): Executed 1 of 1 (1 FAILED) ERROR (0.04 secs / 0.007 secs)

这是我的测试用例:

  it('should attach a list of jackpot to the scope', function () {
    expect(scope.jackpot.length).toBe(2);
  });

这是我尝试运行测试的代码块:

var countInJackpot = localStorageService.get('jackpot');
$scope.jackpot = countInJackpot || [
  {
    letter: '$',
    prize: '$1,000,000 Cash',
    numbers: ['$611A','$612B','$613C','$614D','$615E','$616F','$617G','$618F'],
    count: [0,0,0,0,0,0,0,0]
  },
  {
    letter: '?',
    prize: '$500,000 Vacation Home',
    numbers: ['?619A','?620B','?621C','?622D','?632E','?624F','?625G','?626H'],
    count: [0,0,0,0,0,0,0,0]
  }
];

暂时,我真的只想写一个简单的测试用例,所以它会让我构建应用程序。我目前正在研究单元测试,但我仍然不愿意自己编写更复杂的测试用例。我将保存以供日后使用。

如果需要,我已将文件的全部内容包含在gist中以供参考,如果需要,我可以包含karma.conf.js的内容。

My gist

2 个答案:

答案 0 :(得分:1)

我希望您能够测试localStorageService拥有和没有数据的两种情况。为此,请为localStorageService创建一个间谍(请参阅Spies)并像这样编写测试......

'use strict';

describe('Controller: MainCtrl', function () {

var scope, localStorageService, localData;

beforeEach(function() {
    localData = {};

    module('monopolyApp');

    localStorageService = jasmine.createSpyObj('localStorageService', ['get', 'set']);
    localStorageService.get.and.callFake(function(key) {
        return localData[key];
    });

    inject(function($rootScope) {
        scope = $rootScope.$new();
    });
});

it('assigns jackpots from local storage if present', inject(function($controller) {
    localData.jackpot = 'whatever, does not matter';

    $controller('MainCtrl', {
        $scope: scope,
        localStorageService: localStorageService
    });

    expect(localStorageService.get).toHaveBeenCalledWith('jackpot');
    expect(scope.jackpot).toBe(localData.jackpot);
}));

it('assigns jackpots from default array if none present in local storage', inject(function($controller) {
    $controller('MainCtrl', {
        $scope: scope,
        localStorageService: localStorageService
    });

    expect(localStorageService.get).toHaveBeenCalledWith('jackpot');
    expect(scope.jackpot.length).toEqual(2);

    // maybe include some other checks like
    expect(scope.jackpot[0].letter).toEqual('$');
    expect(scope.jackpot[1].letter).toEqual('?');
}));

});

答案 1 :(得分:1)

在您的测试用例中,范围应该是$ scope?

OR

您可能无法设置测试环境以加载到控制器中。

以下是我测试控制器的一个例子...... Angular使得设置有点不耐烦,但是一旦你理解了流程。这太棒了:))

我会尝试添加尽可能多的评论来解释每件作品......但是如果您需要澄清,请告诉我。您可能正在使用jasmine,但请记住,这是mocha,我使用通过karma.conf加载的角度模拟库。

describe('myController', function() {
  var $scope,
    createController;

  // Runs before each test. Re-extantiating the controller we want to test.
  beforeEach(inject(function($injector) {
    // Get hold of a scope (i.e. the root scope)
    $scope = $injector.get('$rootScope');

    // The $controller service is used to create instances of controllers
    var $controller = $injector.get('$controller');

    createController = function() {
      // Creates the controller instance of our controller.
      //    We are injecting $scope so we will have access to it
      //    after the controllers code runs
      return $controller('myCtrl', {
        '$scope': $scope
      });
    };
  }));

  describe('#myFunction', function() {
    it('jackpot should contain two objects', function() {
      expect($scope.jackpot.length).to.equal(2);
    });
  });
});

希望有所帮助。以下是我以前学过的一些资源:)祝你好运!