Barauna Hugo - Cucumber e RSpec стр 16.

Шрифт
Фон

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

eletronics_products = eletronics.subcategories.map { |sub|

sub.products

}

eletronics_products.flatten!

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

end

end

Queremos modificá-lo usando um custom matcher para ficar

assim:

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)

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

end

end

Para escrever esse custom matcher, iremos mais uma vez utilizar a DSL do RSpec

e extrair a lógica de verificação original para dentro desse matcher:

RSpec::Matchers.define :contain_products do |*products|

match do |category|

subcategories_products = category.subcategories.map { |sub|

sub.products

}

subcategories_products.flatten!

expect(subcategories_products & products).to eq products

end

end

Agora que temos o custom matcher pronto, podemos utilizá-lo no nosso teste

para ficar assim:

describe Category do

it "contains all the products of its subcategories" do

51

3.7. Custom matchers

Casa do Código

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)

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

end

end

Repare que após essa refatoração de extrair uma lógica de verificação complexa

para um custom matcher, o comportamento esperado no nosso teste ficou bem mais

claro.

Outro ponto que ficou melhor é a mensagem de erro do nosso teste. Para vermos

isso, basta rodarmos esse teste e ver a seguinte mensagem:

Failures:

1) Category contains all the products of its subcategories

Failure/Error: expect(eletronics).to

contain_products("MacBook", "iPhone")

expected #<Category:0x007fcb1c0fc460 @name="eletronics",

@subcategories=[]>

to contain products "MacBook" and "iPhone"

Na mensagem de erro já está mais claro que o teste falhou porque a categoria

eletronics não contém os produtos "MacBook" e "iPhone", mas ainda podemos melhorar essa mensagem ainda mais.

A mensagem de erro acima foi gerada automaticamente pelo RSpec a par-

tir do nome do nosso custom matcher.

Como nem sempre a mensagem pa-

drão fica clara, é possível customizá-la. Podemos fazer isso usando o método

failure_message_for_should da DSL de custom matcher do RSpec:

failure_message_for_should do |category|

"expected category #{category.name} to contain products #{products}"

end

O código acima deve ser adicionado dentro da definição do nosso custom mat-

cher:

52

Casa do Código

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

RSpec::Matchers.define :contain_products do |*products|

match do |category|

subcategories_products = category.subcategories.map { |sub|

sub.products

}

subcategories_products.flatten!

expect(subcategories_products & products).to eq products

end

failure_message_for_should do |category|

"expected category #{category.name} to contain products #{products}"

end

end

Agora, ao rodarmos o teste, ele falha com a seguinte mensagem:

Failures:

1) Category contains all the products of its subcategories

Failure/Error: expect(eletronics).to

contain_products("MacBook", "iPhone")

expected category eletronics to contain products ["MacBook", "iPhone"]

Após a customização, a mensagem de erro ficou bem mais clara!

Além dessa opção de customização, o RSpec tem várias outras. Como são muitas,

convido você a olhar a documentação de custom matchers do RSpec (https://www.

relishapp.com/rspec/rspec-expectations/v/2-14/docs/custom-matchers) para ver as

outras opções de customização.

Agora que você já teve a experiência de construir um custom matcher com a

DSL do RSpec, vamos ver melhor o que de fato é um matcher pro RSpec e descobrir

o protocolo de matchers por trás disso tudo.

3.8

Entendendo o protocolo interno de matcher do

RSpec

Na seção anterior nós aprendemos a construir nossos próprios matchers pro RSpec

usando a DSL de custom matchers. Essa DSL server para facilitar a criação de novos

53

3.8. Entendendo o protocolo interno de matcher do RSpec

Casa do Código

matchers, mas ela não é o único modo de criar um matcher novo. Você pode criar seu

próprio matcher se entender o protocolo por trás da relação entre uma expectation

e o seu matcher.

Como vimos na seção 3.1, uma expectation segue a seguinte estrutura básica:

expect(actual).to matcher(expected)

Para ficar mais claro como uma expectation é executada, vamos colocar mais

alguns parênteses nessa estrutura:

expect(actual).to(matcher(expected))

Você pode ver pela linha de código acima que o matcher utilizado não é nada

mais do que um argumento para o método to. O contrato entre esse método e o

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

0
Шрифт
Фон

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