Question

My controller is:

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();
}]);

My test is pretty simple:

(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!
    });

  });
})();

I want to test that the fileService had it's getContents function called and mock a response so that I can test the two scenarios (if is array and if isn't`)

Était-ce utile?

La solution

I would recommend using Jasmine spies for this.

Here is an example that might help. I usually put the spyOn call in the beforeEach.

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

In the 'it' part:

expect(fileService.getContents).toHaveBeenCalled();

To get the response, just call the method in your controller that calls the fileService method. You may need to manually run a digest cycle too. Snippet from one of my tests:

    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 in this case is a promise created with $q.defer();

Autres conseils

You can create a spy and verify only that fileService.getContents is called, or either verify extra calls (like promise resolution) by making the spy call through. Probably you should also interact with httpBackend since you may need to flush the http service (even though you use the mock service).

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

  });
})();

You can also add expectations to what happens inside the callback but you should issue a httpBackend.flush() before.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top