Uma parte legal do Jasmine e que adianta muito o nosso lado são os matchers: de um modo resumido e direto, um _matcher_ implementa uma comparação _booleana_ entre o valor atual e o valor esperado. É responsável em passar para o _framework_ 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. Simplemente 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 anterior toEqual
. A diferença é que toBe
verifica não só se os dois valores são iguais, mas também como 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 commo true ou false, podemos usar respectivamente os _matchers_ toBeTruthy
e toBeFalsy
:
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_ toBeTruthy
e toBeFalsy
é 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
****
“”
undefined
null
NaN
not
Muitas vezes podemos inverter um _matcher_ pra 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 benditos 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 brother 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. É ainda é possível fazer nossos matchers customizados, mas vou deixar isso para um próximo post. Se você se interessar mais pelo assunto, recomendo o livro JavaScript Testing with Jasmine que inclusive li recentemente e tive a idéia de escrever o post.
Acho que é isso. Se encontrar algum erro ou melhoria no post, pode postar no comentário ou pode me chamar no twitter.