CSS
CSS

Reputation: 412

How to test angular app with John Papa style, Karma, and Jasmine with data service?

For some reason, even following the example provided by Josh in the post reply How to test John papa vm.model unit testing with jasmine?, I can't get my controller's values to show up in the testing area. I think it's because of the data service, but it is a necessary component for our SPA, as is using John Papa's styling.

Below is a code snippet to hold the code and display the errors I'm receiving.

(function() {
  'use strict';
  angular.module('tickets')
    .service("DataService", DataService)

  /* @ngInject */
  DataService.$inject = ["$rootScope", "$q"];

  function DataService($rootScope, $q) {
    var vm = this;
    vm.nameDefault = "Name -- Please Authenticate";
    vm.name = vm.nameDefault;
  };

})();

(function() {
  'use strict';
  angular.module('tickets')
    .controller('HomeController', HomeController);

  /* @ngInject */
  HomeController.$inject = ['$scope', '$location', 'DataService'];

  function HomeController($scope, $location, DataService) {
    var vm = this;
    vm.name = DataService.name;
    vm.nameDefault = DataService.nameDefault;
  };

})();
<link href="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.1.0/jasmine.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.1.0/jasmine.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.1.0/jasmine-html.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.1.0/boot.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0-beta.4/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0-beta.4/angular-mocks.js"></script>

<script>
  'use strict';

  describe('Controller: HomeController', function() {

    beforeEach(module('tickets'));

    var controller, $location, DataService;
    var tests = 0;

    beforeEach(inject(function($controller, _$location_, _DataService_) {
      $location = _$location_;
      DataService = _DataService_;
      scope = {};

      controller = $controller('HomeController', {});
    }));

    var controller, scope, $location, DataService;
    var tests = 0;

    /* // This version works up until I try to verify the name and nameDefault in controller \\
     *
     *    beforeEach(inject(function ($rootScope, $controller, _$location_, _DataService_) {
     *        $location = _$location_;
     *        DataService = _DataService_;
     *        scope = $rootScope.$new();
     *
     *        controller = function () {
     *            return $controller('HomeController', {});
     *        };
     *    }));
     */

    afterEach(function() {
      tests += 1;
    });

    describe('local variables', function() {

      describe('load the data model and values for all pertinent variables', function() {
        it('should be instantiated', function() {
          expect(DataService).toBeDefined();
        });
        it('should contain a name with an initial value before authentication', function() {
          expect(DataService.nameDefault).toBe('Name -- Please Authenticate');
          expect(DataService.name).toEqual(DataService.nameDefault);
        });
      });
      describe('should load the controller with data model values, and update as data model values update', function() {
        it('should be instantiated', function() {
          expect(controller).toBeDefined();
        })
        it('should not have a vm attribute that can be reached from here', function() {
          expect(controller.vm).toBeUndefined();
        })
        it('should contain a name with an initial value before authentication, both from the data model', function() {
          expect(controller.name).toBe(DataService.name);
          expect(controller.nameDefault).toBe(DataService.nameDefault);
        });
      });
    });

    it('should have tests', function() {
      expect(tests).toBeGreaterThan(0);
    });
  });
</script>

My code, when I use it in our native environment, works to verify that everything in the data service has been instantiated properly (and using the commented out beforeEach block), but the styling using the example in the question referenced above throws even more errors about the scope not being instantiated, even though it is the same (with added dependencies) as that question.

I would expect the answer to be similar to the (currently unanswered) question: How to test John papa vm.model controllers and factories unit testing with jasmine?

I appreciate any help you guys offer.

-C§

Edit Even though I've answered and have success, I would love to get some feedback on why the implementation below works and the other two attempts do not. This is using Karma version 0.13.8 (latest), jasmine 2.1.0, and Angular 1.4.0.

I know it seems like I came up with the solution pretty quickly, but I've been wrestling with this since Friday afternoon (8/7) and have tried a dozen different formats without success.

Again, I welcome your comments and votes so that I can better understand why the version below works and the others have not, especially since I am still very green to AngularJS (1 month in, now).

Thanks again,

-C§

Upvotes: 2

Views: 2176

Answers (1)

CSS
CSS

Reputation: 412

I get it now. Just had to look at Globally mock object in angularjs for jasmine/karma testing and my brain clicked.

The declaration and beforeEach block in the beginning of the test needs to look like this:

    var controller, scope, $location, DataService;
    var tests = 0;

    beforeEach(inject(function ($rootScope, $controller, _$location_, _DataService_) {
    $location = _$location_;
    DataService = _DataService_;
    scope = $rootScope.$new();

    controller = $controller('HomeController', {
            $scope: scope
        });
    }));

I think since I've messed with our initial setup a little too much (started the SPA from a template), I needed a strange implementation to make it all work. I'm now getting successful tests throughout:

enter image description here

I hope this helps someone else with similar issues.

Upvotes: 2

Related Questions