jeudi 31 décembre 2015

How to use ngMock to inject $controller

I'm trying to learn unit testing for Angular using Karma, Jasmine, and ngMock. There are at least 2 places in the Angular docs that show how to write unit tests for a controller, and I just have a couple of questions about how they're doing things.

From the Controller docs, section on testing controllers:

describe('myController function', function() {

  describe('myController', function() {
    var $scope;

    beforeEach(module('myApp'));

    beforeEach(inject(function($rootScope, $controller) {
      $scope = $rootScope.$new();
      $controller('MyController', {$scope: $scope});
    }));

    it("...");
  });
});

Question 1: This one mostly makes sense to me, but here's something I don't quite get. I understand that $controller is grabbing an instance of "MyController", but it looks like what is returned isn't being saved or used anywhere, so the only thing I can think of is that we grab that controller in order to get the correct $scope object? Even that seems like it isn't being saved in a variable anywhere, so I'm still a little confused on how this works behind the scenes. I had the same confusion about how module() works because we seem to be declaring which module we're using, but not saving or using it anywhere else. Is there something behind the scenes that caches the module/controller/scope so we don't have to save it manually or something?


Here's another example from the Unit Testing docs:

describe('PasswordController', function() {
  beforeEach(module('app'));

  var $controller;

  beforeEach(inject(function(_$controller_){
    // The injector unwraps the underscores (_) from around the parameter names when matching
    $controller = _$controller_;
  }));

  describe('$scope.grade', function() {
    it('sets the strength to "strong" if the password length is >8 chars', function() {
      var $scope = {};
      var controller = $controller('PasswordController', { $scope: $scope });
      $scope.password = 'longerthaneightchars';
      $scope.grade();
      expect($scope.strength).toEqual('strong');
    });
  });
});

Question 2: Here in the beforeEach function it's doing the underscore wrapping thing. Is that just so that you can keep the same service name throughout without having to change it?

Question 3: The it() block then uses $controller to do its thing, this time saving what gets returned to var controller but seemingly still never using it beyond this point. So why save it to a variable? The only thing I can think of offhand is that you save it in case you need to use it again inside this it() block, but they just didn't in this example?


I've been looking all over for a good explanation and I can't seem to find one. Sorry if there's a silly explanation I'm missing, but I'm on a time crunch and can't spend any more time spinning my wheels.

Aucun commentaire:

Enregistrer un commentaire