AngularJS, Jasmine, Karma: Testando diretivas

Se você ainda não teve a experiência de usar o ngMock com Jasmine, não sabe o que está perdendo, é tudo muito maravilhoso e poderoso. Continue lendo, vamos lá!

Como falei no final do artigo AngularJS: Criando testes com Jasmine e Karma, você pode usar o $injector do AngularJS para chamar em qualquer lugar tudo aquilo que precisamos para trabalhar com nossos módulos, neste guia nós utilizaremos as seguintes dependências:

  • $injector
  • $rootScope
  • $compile

Importando as dependências

Vamos começar chamando as nossas dependências dentro do nosso teste:

describe(‘app module’, function () {
var $compile, $rootScope;

beforeEach(module('app'));

beforeEach(inject(function ($injector) {
    $compile = $injector.get('$compile');
    $rootScope = $injector.get('$rootScope');
}));

});
Logo acima importamos as dependências que serão reutilizadas pelas próximas suítes, agora vamos importar as dependências da nossa diretiva:

describe(‘app module’, function () {
var $compile, $rootScope;

beforeEach(module('app'));

beforeEach(inject(function ($injector) {
    $compile = $injector.get('$compile');
    $rootScope = $injector.get('$rootScope');
}));

describe('replacer directive', function () {
    var element, scope, form;

    beforeEach(inject(function ($injector) {
        scope = $rootScope.$new();
    }));
});

});
Agora precisamos compilar o nosso elemento dentro da suíte replacer directive , faremos da seguinte maneira:

    describe(‘replacer directive’, function () {
var element, scope, form;

    beforeEach(inject(function ($injector) {
        scope = $rootScope.$new();
        element = '<form>' + '<input ng-model="text" name="text" replacer-directive>' + '</form>';
        element = angular.element(element);
        element = $compile(element)(scope);
    }));
});</pre>

Agora você deve estar se perguntando:

Como diabos eu vou pegar o meu input? Vou ter que fazer malabarismos com jQuery ou document.querySelector?
Resposta: NÃO! Basta dar um valor para a única variável que ainda não definimos dentro da suíte replacer directive :

beforeEach(inject(function ($injector) {
scope = $rootScope.$new();
element = ‘<form>’ + ‘<input ng-model=”text” name=”text” replacer-directive>’ + ‘</form>’;
element = angular.element(element);
element = $compile(element)(scope);
form = scope.form;
scope.$digest();
}));

Agora podemos acessar ao nosso input através da variável form , da seguinte forma:

form.text

Note que utilizamos um novo método na penúltima linha, o scope.$digest() , ele cuidará de atualizar o scope, todas as modificações que fizer no scope deve conter um scope.$digest() após para que todas as modificações sejam aplicadas ao DOM.

Agora nós podemos fazer os nossos testes:

it(‘should replace 2 with 3’, function () {
scope.text = 252;
scope.$digest();

expect(form.text).toBe(352);
});
A partir daí podemos ser felizes para sempre e testar as nossas diretivas de todas as maneiras possíveis para que tudo funcione exatamente como esperado.

Como já sabem, deixem suas dúvidas nos comentários. Um abraço a todos e até a próxima!