使用$httpBackend测试Jasmine/Karma的AngularJS不起作用

Testing AngularJS with Jasmine / Karma with $httpBackend not working

本文关键字:Karma AngularJS 不起作用 Jasmine httpBackend 测试 使用      更新时间:2023-09-26

我正试图通过Karma与Jasmine一起对我的应用程序进行基于Angular的单元测试。该应用程序包括调用GitHub API,提取用户所有转发的名称,并用这些名称填充数组。我正在尝试测试数组是否已填充,但$httpBackend出现了一些问题。

我的控制器的相关部分是:

readmeSearch.controller('ReadMeSearchController', ['RepoSearch', function(RepoSearch) {
  var self = this;
  self.gitRepoNames = [];
  self.doSearch = function() {
    var namesPromise =
      RepoSearch.query(self.username)
        .then(function(repoResponse) {
          addRepoNames(repoResponse);
        }).catch(function(error) {
          console.log('error: ' + error);
        });
    return namesPromise;
  };
  addRepoNames = function(response) {
    self.repoSearchResult = response.data;
    for(var i = 0; i < self.repoSearchResult.length; i++) {
      var name = self.repoSearchResult[i]['name']
      self.gitRepoNames.push(name);
    };
  };
}]);

我的RepoSearch工厂是:

readmeSearch.factory('RepoSearch', ['$http', function($http) {
  return {
    query: function(searchTerm) {
      return $http({
        url: 'https://api.github.com/users/' + searchTerm + '/repos',
        method: 'GET',
        params: {
          'access_token': gitAccessToken
        }
      });
    }
  };
}]);

有问题的测试是:

describe('ReadMeSearchController', function() {
  beforeEach(module('ReadMeter'));
  var ctrl;
  beforeEach(inject(function($controller) {
    ctrl = $controller('ReadMeSearchController');
  }));
  describe('when searching for a user''s repos', function() {
    var httpBackend;
    beforeEach(inject(function($httpBackend) {
      httpBackend = $httpBackend
      httpBackend
        .expectGET('https://api.github.com/users/hello/repos?access_token=' + gitAccessToken)
        .respond(
        { data: items }
      );
    }));
    afterEach(function() {
      httpBackend.verifyNoOutstandingExpectation();
      httpBackend.verifyNoOutstandingRequest();
    });
    var items = [
      {
        "name": "test1"
      },
      {
        "name": "test2"
      }
    ];
    it('adds search results to array of repo names', function() {
      ctrl.username = 'hello';
      ctrl.doSearch();
      httpBackend.flush();
      expect(ctrl.gitRepoNames).toEqual(["test1", "test2"]);
    });
  });
});

当我运行测试时,我得到错误

应[]等于["test1","test2"]。

很明显,这是因为self.gitRepoNames没有被填充。当我在测试中的预期之前控制台日志ctrl.repoSearchResult时,我得到

Object{data: [Object{name: ...}, Object{name: ...}]}

这就是问题所在,因为当在addRepoNames函数的for循环中调用self.repoSearchResult.length时,它将是未定义的。

所以我的问题是,为什么response.data在测试中的addRepoNames函数中被调用时不返回数组?

如有任何帮助,我们将不胜感激。

编辑:我应该提到的是,该应用程序在服务器上运行时运行良好。

ctrl.doSearch是一个异步函数。您应该以异步方式处理它。尝试:

it('adds search results to array of repo names', function(done) {
  ctrl.username = 'hello';
  ctrl.doSearch().then(function() {
    expect(ctrl.gitRepoNames).toEqual(["test1", "test2"]);
    done();
  });
  httpBackend.flush();      
});