Front End

3 jun, 2015

Jasmine: entendendo os matchers

Publicidade

Há algum tempo atrás escrevi sobre Jasmine, mais uma introdução sobre o framework e como escrever testes era algo intuitivo e fácil. Se você tem interesse, o artigo é o: Brincando com Jasmine.

Uma parte legal do Jasmine e que adianta muito o nosso lado é o matcher, que de um modo resumido, implementa uma comparação booleana entre o valor atual e o valor esperado. É responsável em passar para o Jasmine se o que esperamos através do nosso teste é verdadeiro ou falso. Com base nisso, o Jasmine vai passar ou falhar a spec.

toEqual

Esse talvez seja o mais básico e um dos que mais iremos usar. Simplesmente verifica se duas coisas são iguais (e não necessariamente o mesmo objeto). Por exemplo, as seguintes expects iriam passar:

expect(true).toEqual(true);
expect([1, 2, 3]).toEqual([1, 2, 3]);

Da mesma forma, as seguintes iriam falhar:

expect(5).toEqual(12);
expect([1, 2, 3]).toEqual([11, 12, 13])

toBe

O matcher toBe, a princípio, parece ser igual ao toEqual. A diferença é que toBe verifica não só se os dois valores são iguais, mas também se eles são do mesmo objeto.

Pra podermos ver a diferença entre os dois:

var bob = { model: "Camaro" };
var john = { model: "Camaro" };

expect(bob).toEqual(john); // passa => são equivalentes
expect(bob).toBe(john); // falha => não é o mesmo objeto

Apesar de bob e john serem similares, eles não são o mesmo objeto, o que faz a spec passar se for usado o matcher toEqual, mas falha se for usado o matcher toBe. O mesmo acontece para arrays:

var group = [100, 101, 102];

expect(group).toEqual([100, 101, 102]); // passa => são equivalentes
expect(group).toBe([100, 101, 102]); // falha => não é o mesmo array

toBeTruthy e toBeFalsy

Para testar se algum valor é avaliado como true ou false, podemos usar respectivamente os matchers toBeTruthytoBeFalsy:

expect(true).toBeTruthy();
expect(1000).toBeTruthy();
expect({}).toBeTruthy();

expect("").toBeFalsy();
expect(null).toBeFalsy();
expect(false).toBeFalsy();

Se pararmos pra olhar com calma o exemplo anterior, podemos notar que a avaliação dos matchers toBeTruthytoBeFalsy é idêntica ao JavaScript. Então, temos alguns valores específicos que são considerados falsy e todo o restante é avaliado como truthy. Pra nossa referência, uma lista dos valores que são avaliados como falsy pelo Jasmine:

  • false
  • 0
  • ""
  • undefined
  • null
  • NaN

not

Muitas vezes podemos inverter um matcher para termos certeza de que ele não é um valor true. Podemos fazer isso facilmente adicionando o prefixo .not:

expect('Fabeni').not.toEqual('Finelli');

toContain

Conseguimos também verificar se um elemento está contido em um array ou string por exemplo, como o matcher  toContain.

expect([10, 11, 12, 13, 14, 15]).toContain(13);
expect('Raphael Fabeni').toContain('Fabeni');

toBeDefined e toBeUndefined

Da mesma maneira que vimos os matchers toBeTruthy e toBeFalsy, Jasmine também nos oferece os toBeDefined e toBeUndefined que verificam se um valor é defined ou undefined.

var iAmUndefined;
expect(null).toBeDefined(); // passa
expect('Fabeni').toBeDefined(); // passa
expect(iAmUndefined).toBeDefined(); // falha

expect(iAmUndefined).toBeUndefined(); // passa
expect(12).toBeUndefined(); // falha
expect(null).toBeUndefined(); // falha

toBeNull

Direto ao ponto, esse matcher simplesmente avalia se um valor é null:

expect(null).toBeNull(); // passa
expect(false).toBeNull(); // falha
expect(1).toBeNull(); // falha

toBeNaN

Sem muitas delongas, esse matcher verifica se um valor é NaN:

expect(0).toBeNaN(); // falha
expect(10).not.toBeNaN(); // passa

toBeGreatherThan e toBeLessThan

Esses dois matchers verificam se um valor é maior ou menor que um outro valor passado.

expect(10).toBeGreatherThan(1); // passa
expect(10).toBeLessThan(20); // passa

toBeCloseTo

Esse matcher permite que possamos verificar se um certo número está próximo de um outro número, dado uma certa precisão decimal como segundo argumento. Poderíamos por exemplo, verificar se um número é próximo de 25.23 com um ponto decimal. Poderíamos fazer algo assim:

expect(25.23).toBeCloseTo(25.2, 1); // passa

toMatch

Esse cara verifica se algum valor está de acordo com base em uma expressão regular.

expect('Yes, we can!').toMatch(/we/); // passa

toThrow

Esse matcher permite que verifiquemos se uma função lançou um erro. Como exemplo, vamos imaginar que temos uma função onlyNumbers que deve lançar uma exceção caso o argumento passado seja uma string e não um número. Podemos usar aqui uma função anônima para nos facilitar a vida:

expect(function() {
    onlyNumbers('argumento errado')
}).toThrow();

Ufa…

Deu pra ver que o framework nos oferece um monte de opção para utilizarmos em nossos testes. E ainda é possível fazer nossos matchers customizados, mas vou deixar isso para um próximo artigo. Se você se interessar mais pelo assunto, recomendo o livro JavaScript Testing with Jasmine, que inclusive li recentemente e tive a ideia de escrever o artigo.

Gostou? Escrevi alguma groselha? Quer melhorar? Abra uma issue com a hashtag 1postperweek e vamos conversar.

***

Artigo publicado originalmente em: http://www.raphaelfabeni.com.br/jasmine-entendendo-matchers/