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

Angularjs scope.variable上的角度控制器测试未定义,angularjs,unit-testing,angularjs-scope,jasmine,angularjs-controller,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.eSearchDiction

我正在尝试使用$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未定义。单元测试现在已经超出了我的想象,我根本不知道自己在做什么。如果您对这个特定问题有一个解决方案,对所有代码有任何建议,或者愿意给我发消息并给我一些指导,那就太棒了。

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

.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 });
  }
})

你有两个问题在你的期望和设置

1) 您正在测试控制器及其作用域,对控制器方法的操作以及对控制器作用域的设置值也是如此

2) 而不是执行
Eword=“englishWord”您应该设置控制器作用域的值
scope.eword=“englishWord”

3) 您需要调用作用域上的方法,即
scope.esearch dictionary(),而不是直接调用服务方法
DictionaryService.getByEword({eng:Eword})
这样,当解析方法时,它将使用相应的数据进行解析,并将其设置在作用域上

4) 请注意,当您直接针对
scope.word
进行测试时,您可能无法获得所需的结果,因为结果对象上会有其他属性,如
$promise
。因为您直接分配结果

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

尝试:-


Expection utility方法的某些语法与您使用的不同,您可以使用与您使用的相同的语法,我只是为演示做的

很好,非常感谢!这是一个可以接受的单元测试,还是我应该测试其他东西?@Benoit,不客气。根据您正在做的事情,您可以为您可能想要测试控制器的各种场景编写不同的测试块。您也可以在不同的块中测试jSearch字典。此外,当您有多个测试块时,您可以将常见的初始化内容移动到每个块之前,例如:-资源模拟、控制器创建、后端模拟等。。
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();

}));