Barauna Hugo - Cucumber e RSpec стр 15.

Шрифт
Фон

rificar que os produtos delas estão contidos na categoria "eletronics":

47

3.7. Custom matchers

Casa do Código

describe Category do

it "contains all the products of its subcategories" do

eletronics = Category.new("eletronics")

computers

= Subcategory.new("computers")

cell_phones = Subcategory.new("cell phones")

computers.add_product("MacBook")

cell_phones.add_product("iPhone")

eletronics.add_subcategories(computers, cell_phones)

eletronics_products = eletronics.subcategories.map { |sub|

sub.products

}

eletronics_products.flatten!

expect(eletronics_products).to include("MacBook", "iPhone")

end

end

Perceba como a intenção da lógica de verificação desse teste não está 100% clara:

eletronics_products = eletronics.subcategories.map { |sub|

sub.products

}

eletronics_products.flatten!

expect(eletronics_products).to include("MacBook", "iPhone")

Só de bater o olho nesse código não da para dizer que a intenção dele é verificar

que a categoria "eletronics" contém os produtos "MacBook" e "iPhone".

Esse é o primeiro ponto a melhorar.

O segundo ponto a melhorar nós podemos identificar ao rodar o teste e ler sua

mensagem de erro:

1) Category contains all the products of its subcategories

Failure/Error:

expect(eletronics_products).to

include("MacBook", "iPhone")

expected [] to include "MacBook" and "iPhone"

A mensagem de erro não fala explicitamente que o erro é que a categoria

"eletronics" não contém nenhum dos produtos que ela deveria conter. Lembre-

se que a mensagem de erro de um teste é muito importante, pois uma mensagem de

erro clara pode nos ajudar a resolver mais rápido um teste que está quebrado.

48

Casa do Código

Capítulo 3. Introdução ao básico do RSpec

Então pelo menos esses dois pontos nós podemos melhorar no nosso teste, a

clareza da intenção da lógica de verificação e a mensagem de erro do teste. Para

fazer essa melhora podemos escrever um custom matcher do RSpec e utilizá-lo para

refatorar a verificação do nosso teste para ficar assim:

expect(eletronics).to contain_products("MacBook", "iPhone")

Vamos aprender a como fazer um custom matcher do RSpec.

Escrevendo um custom matcher do RSpec

O RSpec nos oferece uma DSL para escrever um custom matcher de modo bem

simples. Para entender essa DSL, vamos escrever um custom matcher que serve para

verificar se um número é múltiplo de 7. Esse matcher poderá ser usado do seguinte

modo:

expect(21).to be_a_multiple_of(7)

O primeiro passo para escrevermos o custom matcher acima é utilizar o método

RSpec::Matchers.define da DSL do RSpec:

RSpec::Matchers.define :be_a_multiple_of

O método define cria um método nomeado segundo o argumento que foi

passado para ele, no nosso caso o método be_a_multiple_of. Continuando a

seguir a DSL, é necessário passar um bloco para esse método:

RSpec::Matchers.define :be_a_multiple_of do |expected|

end

Repare no argumento que é passado para o bloco, o expected. Esse argumento

é o mesmo que é passado para o nosso matcher na hora que é utilizado. Logo, quando

utilizarmos be_a_multiple_of(7), o valor de expected será 7.

Para finalizar o nosso matcher, é necessário colocar a lógica de verificação dentro

dele, ou seja, a lógica para checar se um número é múltiplo de outro. Podemos fazer

isso checando se o resto da divisão entre o número testado e o argumento passado

para o matcher é zero:

RSpec::Matchers.define :be_a_multiple_of do |expected|

match do |actual|

(actual % expected) == 0

end

end

49

3.7. Custom matchers

Casa do Código

Repare que para implementar a lógica de verificação utilizamos o método

match. Chamamos esse método passando um bloco pra ele com um argumento,

o actual, que é o objeto sendo testado. No exemplo que estamos usando:

expect(21).to be_a_multiple_of(7)

actual é o 21 (objeto sendo testado) e o expected é o 7 (argumento passado

para o matcher).

Pronto, isso é o mínimo necessário para escrevermos nosso próprio matcher.

Com esse matcher pronto, poderíamos escrever um teste do seguinte modo:

RSpec::Matchers.define :be_a_multiple_of do |expected|

match do |actual|

(actual % expected) == 0

end

end

describe "The be_a_multiple_of custom matcher" do

it "can be used to verify if a number is a multiple of another one" do

expect(21).to be_a_multiple_of(7)

expect(15).to be_a_multiple_of(3)

expect(7).not_to be_a_multiple_of(3)

end

end

Agora que já sabemos como construir nosso próprio matcher, vamos voltar ao

nosso objetivo inicial, escrever um matcher para verificar que uma categoria contém

um ou mais produtos.

O teste que escrevemos para a categorização de produtos está até então do se-

guinte modo:

describe Category do

it "contains all the products of its subcategories" do

eletronics = Category.new("eletronics")

computers

= Subcategory.new("computers")

cell_phones = Subcategory.new("cell phones")

computers.add_product("MacBook")

cell_phones.add_product("iPhone")

eletronics.add_subcategories(computers, cell_phones)

50

Casa do Código

Ваша оценка очень важна

0
Шрифт
Фон

Помогите Вашим друзьям узнать о библиотеке