scope.variable上的角度控制器测试未定义

时间:2014-10-15 23:53:06

标签: angularjs unit-testing angularjs-scope jasmine angularjs-controller

我试图用$ resource学习角度单位测试。

这里我有一个简单的控制器:

.controller('DictionaryCtrl', function ($scope, DictionaryService) {

  $scope.jSearchDictionary = function () {
    $scope.word = DictionaryService.getByJword({ jp: $scope.jword });
  }

  $scope.eSearchDictionary = function () {
    $scope.word = DictionaryService.getByEword({ eng: $scope.eword });
  }
})

在我看来,我有2 ng-submit(jSearchDictionary和eSearchDictionary),我绑定了搜索到的相应单词(jword或eword)。

服务也很简单:

.factory('DictionaryService', function ($resource) {
  return $resource('http://127.0.0.1:3000/api/nlp/words', {}, {
    getByJword: { method: 'GET', params: { jp: '@jword' } },
    getByEword: { method: 'GET', params: { en: '@eword' } },
  })
})

最后,这是我的测试。

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

beforeEach(function () {
  this.addMatchers({
    toEqualData: function (expected) {
      return angular.equals(this.actual, expected);
    }
  });
});

beforeEach(module('gakusei'));

describe('nlpCtrl', function () {
var scope,
    $controller,
    $httpBackend,
    $stateParams,
    Eword,
    mockWord = [
    {
      "words": [
          {
            "readings": [
                "ホッケー"
            ]
          }
      ],
      "count": 1
    }];

beforeEach(inject(function (_$httpBackend_, $rootScope, _$controller_) {
  scope = $rootScope.$new();
  $controller = _$controller_;
  $httpBackend = _$httpBackend_;
}));

afterEach(function () {
  $httpBackend.verifyNoOutstandingExpectation();
  $httpBackend.verifyNoOutstandingRequest();
});

it('should get a word', inject(function (DictionaryService) {
  Eword = "englishWord";
  $httpBackend.expectGET('http://127.0.0.1:3000/api/nlp/words?eng=englishWord')
    .respond(mockWord[0]);

  var ctrl = $controller('DictionaryCtrl', { $scope: scope });
  var request = DictionaryService.getByEword({ eng: Eword })

  $httpBackend.flush();

  expect(scope.word).toEqualData(mockWord[0]);
  expect(BasketService.getByJword).toBeTruthy();
  expect(BasketService.getByEword).toBeTruthy();
}));
});
});

问题在于:

expect(scope.word).toEqualData(mockWord[0]);

scope.word未定义。单位测试现在已经超出我的想象,我不确定我在做什么。如果您有解决这个特定问题的解决方案,请对所有代码提出任何建议,或者愿意给我发信息并指导我一点,那就太棒了。

2 个答案:

答案 0 :(得分:1)

您的期望和设置存在几个问题。

1)您正在测试控制器及其范围,因此对控制器方法执行操作并在控制器范围上设置值。

2)您应该在控制器范围Eword = "englishWord";上设置值,而不是scope.eword = "englishWord";

3)不是直接调用服务方法DictionaryService.getByEword({ eng: Eword }),而是需要调用范围上的方法,即scope.eSearchDictionary();,以便在解析方法时解析相应的数据并将其设置为范围。

4)请注意,当您直接对scope.word进行测试时,可能无法得到所需的结果,因为结果对象上会有$promise等其他属性。由于您直接指定结果。

5)我不确定你是否需要最后2个期望。

尝试: -

it('should get a word', inject(function (DictionaryService) {
  scope.eword = "englishWord";
  $httpBackend.expectGET('http://127.0.0.1:3000/api/nlp/words?eng=englishWord')
    .respond(mockWord[0]);

  $controller('DictionaryCtrl', { $scope: scope });

  scope.eSearchDictionary();

  $httpBackend.flush();

  expect(scope.word.words[0]).toEqual(mockWord[0].words[0]);

  /*I dont think you need the following expectations at all*/
  expect(DictionaryService.getByJword).toBeDefined();
  expect(DictionaryService.getByEword).toBeDefined();

}));

<强> Plnkr

期望效用方法的某些语法与您使用的不同,您可以使用与您使用的相同,我只是为演示

答案 1 :(得分:0)

您正在寻找的变量不存在于这两个函数之外。尝试在控制器的顶部定义它,如下所示:

.controller('DictionaryCtrl', function ($scope, DictionaryService) {

  $scope.word = '';

  $scope.jSearchDictionary = function () {
    $scope.word = DictionaryService.getByJword({ jp: $scope.jword });
  }

  $scope.eSearchDictionary = function () {
    $scope.word = DictionaryService.getByEword({ eng: $scope.eword });
  }
})