0

我的控制器是:

angularMoonApp.controller('SourceController', ['$scope', '$rootScope', '$routeParams', 'fileService', function ($scope, $rootScope, $routeParams, fileService) {
  $scope.init = function() {
    $rootScope.currentItem = 'source';

    fileService.getContents($routeParams.path).then(function(response) {
      $scope.contents = response.data;
      $scope.fileContents = null;
      if(_.isArray($scope.contents)) {
        // We have a listing of files
        $scope.breadcrumbPath = response.data[0].path.split('/'); 
      } else {
        // We have one file
        $scope.breadcrumbPath = response.data.path.split('/');
        $scope.breadcrumbPath.push('');

        $scope.fileContents = atob(response.data.content);

        fileService.getCommits(response.data.path).then(function(response) {
          $scope.commits = response.data;
        });
      }
    });
  }

  $scope.init();
}]);

我的测试很简单:

(function() {
  describe('SourceController', function() {
    var $scope, $rootScope, $httpBackend, createController;

    beforeEach(module('angularMoon'));

    beforeEach(inject(function($injector) {
      $httpBackend = $injector.get('$httpBackend');
      $rootScope = $injector.get('$rootScope');
      $scope = $rootScope.$new();

      var $controller = $injector.get('$controller');

      createController = function() {
        return $controller('SourceController', {
          '$scope': $scope
        });
      };
    }));

    it("should set the current menu item to 'source'", function() {
      createController();
      $scope.init();
      expect($rootScope.currentItem).toBe('source');
    });

    it("should get the contents of the root folder", function() {
      createController();
      $scope.init();

      // NOT SURE WHAT TO DO HERE!
    });

  });
})();

我想测试是否调用fileService了它的getContents函数并模拟了一个响应,以便我可以测试这两种情况(如果是数组,如果不是)

4

2 回答 2

2

我建议为此使用 Jasmine 间谍。

这是一个可能有帮助的例子。我通常将 spyOn 调用放在 beforeEach 中。

var mockedResponse = {};
spyOn(fileService, "getContents").andReturn(mockedResponse);

在“它”部分:

expect(fileService.getContents).toHaveBeenCalled();

要获得响应,只需调用控制器中调用 fileService 方法的方法。您可能还需要手动运行摘要循环。我的一项测试的片段:

    var testOrgs = [];
    beforeEach(inject(function(coresvc) {
        deferred.resolve(testOrgs);
        spyOn(coresvc, 'getOrganizations').andReturn(deferred.promise);

        scope.getAllOrganizations();
        scope.$digest();
    }));

    it("getOrganizations() test the spy call", inject(function(coresvc) {
        expect(coresvc.getOrganizations).toHaveBeenCalled();
    }));

    it("$scope.organizations should be populated", function() {
        expect(scope.allOrganizations).toEqual(testOrgs);
        expect(scope.allOrganizations.length).toEqual(0);
    });

在这种情况下,deferred 是使用 $q.defer() 创建的承诺;

于 2014-05-07T15:50:49.603 回答
1

您可以创建一个间谍并仅验证fileService.getContents被调用的内容,或者通过进行间谍调用来验证额外的调用(如承诺解析)。可能您还应该与 httpBackend 交互,因为您可能需要刷新 http 服务(即使您使用模拟服务)。

(function() {
  describe('SourceController', function() {
    var $scope, $rootScope, $httpBackend, createController, fileService;

    beforeEach(module('angularMoon'));

    beforeEach(inject(function($injector) {
      $httpBackend = $injector.get('$httpBackend');
      $rootScope = $injector.get('$rootScope');
      $scope = $rootScope.$new();

      // See here
      fileService = $injector.get('fileService');
      spyOn(fileService, 'getContents').andCallThrough();

      var $controller = $injector.get('$controller');

      createController = function() {
        return $controller('SourceController', {
          '$scope': $scope
          'fileService': fileService
        });
      };
    }));

    it("should get the contents of the root folder", function() {
      createController();
      $scope.init();

      expect(fileService.getContents).toHaveBeenCalled();
    });

  });
})();

您还可以对回调内部发生的事情添加期望,但您应该在之前发出httpBackend.flush()

于 2014-05-07T15:51:43.323 回答