单元测试的角控制器和服务,它使用一个承诺?(Unit test an angular control

2019-09-29 07:08发布

我不能得到的测试结果通过我使用了一个非常基本的实现来理解测试更深。

我有一个工厂,返回一个承诺,从我的控制器访问。 我想测试呼叫成功并分配到的响应repos变种。 以下是代码:

'use strict';

angular.module('app')
  .factory('searchServ', function ($timeout, $q, $http) {
    return {
      fetch: function(user) {
        var deferred = $q.defer();

        $timeout(function(){
          $http({method: 'GET', url: 'https://api.github.com/users/' + user + '/repos'}).then(function(repos) {
            deferred.resolve(repos.data);
          }, function(reason){
            deferred.reject(reason.status);
            console.log(reason);
          });
        }, 30);

        return deferred.promise;
      }
    };
  })
  .controller('MainCtrl', function ($scope, searchServ) {
    $scope.results = function(user) {
      $scope.message = '';
      searchServ.fetch(user).then(function (repos) {
        if(repos.length){
          $scope.message = '';
          $scope.repos = repos;
        }
        else{
          $scope.message = 'not found'
        }
      }, function (){
        $scope.message = 'not found';
      });
    };
  });

//Test

'use strict';

describe('MainCtrl', function () {
  var scope, searchServ, controller, deferred, repos = [{name: 'test'}];
  // load the controller's module
  beforeEach(module('app'));

  beforeEach(inject(function($controller, $rootScope, $q) {
    searchServ = {
      fetch: function () {
        deferred = $q.defer();
        return deferred.promise;
      }
    };
    spyOn(searchServ, 'fetch').andCallThrough();
    scope = $rootScope.$new();
    controller = $controller('MainCtrl', {
      $scope: scope,
      fetchGithub: fetchGithub
    });


  }));
  it('should test', function () {
    expect(scope.test).toEqual('ha');
  });

  it('should bind to scope', function () {
    scope.results();
    scope.$digest();
    expect(scope.message).toEqual('');
    //expect(scope.repos).not.toBe(undefined);
  });
});

运行这个测试给我下面的错误:

TypeError: undefined is not a function (evaluating 'spyOn(searchServ, 'fetch').andCallThrough()') in test/spec/controllers/main.js (line 15)

任何想法如何测试这个使得其测试范围的结合,以及异步调用?

Answer 1:

有很多的问题与您的代码。

我创建这个Plunkr为宗旨。 index.js是与您的代码和测试用例的文件。 我根据惯例和最佳做法编辑大多数部分。

还有我想给你几个指针:

  • 由于$http返回一个承诺,你应该使用,而不是解决的承诺,建立从您的方法的另一个承诺。 不知道为什么被暂停使用。 所以我删除$q$timeoutsearchServ的依赖。
  • 我通过删除的确在测试情况相同的deferred ,你使用的变量。
  • 你应该用angular-mocks.js嘲笑你的服务和其他相关性,而不是你的测试用例中定义服务(你已经做的方式。)
  • 你应该创建单独describe了测试代码(的不同部分块controller在这种情况下)。

希望这可以帮助!



文章来源: Unit test an angular controller and service which uses a promise?