Dubles de teste

Post on 27-Aug-2014

88 Views

Category:

Software

4 Downloads

Preview:

Click to see full reader

DESCRIPTION

Apresentação simples e direta sobre os cinco tipos de dublês: stub, fake, dummy, mock e spy.

Transcript

Dublês de Teste@marcosbrizeno

Mocks ou Dublês

Mock -> Um tipo de Dublê

Dublê -> Stub,Fake,Dummy,Spy e Mock

Formalmente -> Dublê de Teste (Test Double)

Informalmente -> Mock

Stubs

Substitui um comportamento

Pode retornar um valor

def find_overpriced_items_in(items_list) items = Item.find(items_list) items.select do |item| average_price = AveragePrice::Service.get_average_price(item.global_id) item.price > (average_price * 1.2) endend

should "return all overpriced items in the list" do overpriced_item = Factory.create_item :price => 125 AveragePrice::Service.stubs(:get_average_price).returns(100) assert_equal [overpriced_item], find_overpriced_items_in([overpriced_item])end

ExemploWeb

service

Stub do web service

Fake

Substitui um objeto

module AveragePrice class Service def get_average_price(global_id) 100 end endend

Exemplo

should "return all overpriced items in the list" do overpriced_item = Factory.create_item :price => 125 assert_equal [overpriced_item], find_overpriced_items_in([overpriced_item])end

Fake

Podem ter regras

module AveragePrice class Service ITEM_PRICE_100 = 1 ITEM_PRICE_200 = 2 def get_average_price(global_id) return 100 if(global_id == ITEM_PRICE_100) return 200 if(global_id == ITEM_PRICE_200) 150 end endend

Exemplo

Stub vs Fake

Dummy

Substitui um objeto

Não possui lógica

class DummyItem def method_missing(method, *args, &block) nil endend

Exemplo

Dummy

Exemplo

should "return false if item price is less or equal than 20% plus average price" do dummy_item = DummyItem.new promo_item = PromoItem.new(dummy_item, :price => 100) AveragePrice::Service.stubs(:get_average_price).returns(120) assert_false promo_item.overpriced?end

should "return false if item price is less or equal than 20% plus average price" do promo_item = PromoItem.new(nil, :price => 100) AveragePrice::Service.stubs(:get_average_price).returns(120) assert_false promo_item.overpriced?end

tanto faz

Dummy

Fake vs Dummy

Dummy é um Fake simplificado

Fake vs DummyVoce pode não saber que usa

Mock

Testar chamada de métodos

Parâmetros

Número de vezes

class PromoItem def initialize(item) @item = item end! def overpriced? price > (AveragePrice::Service.get_average_price(@item.global_id)*1.2) endend

should "use AveragePrice service to get the average price" do item = Factory.create_item(:global_id => 99) promo_item = PromoItem.new(item, :price => 100)! AveragePrice::Service.expects(:get_average_price).with(item.global_id).once promo_item.overpriced?end

Exemplo

chamada esperada

uma única vez

parâmetro específico

Spy

Testar chamada de métodos

Parâmetros

Número de vezes

def remove_overpriced_items_in(items) items.reject do |item| item.overpriced? endend

should "use AveragePrice service to get the average price" do item_spy = mock() remove_overpriced_items_in([item_spy]) assert_received(item_spy, :overpriced) do |expect| expect.once endend

Exemplo

chamada esperadauma única

vez

Mock vs Spy

Configuração

Ação

Asserção

Configuração

Expectativa

Ação

Mock vs SpyAlto acoplamento

Só Dublê

Rápidos

IsoladosSem significado

Só Dublêshould “break hope in humanity" do item = Item.new item.stubs(:price).returns(200) assert_equal 200, item.priceend

Sem Dublê

Dependências explícitas

Teste real

Impossível

Sem Dublêdef promo_items_not_sold PromoItems.all( :conditions => ["created_on <= ? AND sold != ?”, DateTime.now - 2.days, true])end

Moar links

http://blog.8thlight.com/uncle-bob/2014/05/14/TheLittleMocker.html

https://www.destroyallsoftware.com/blog/2014/test-isolation-is-about-avoiding-mocks

http://www.thoughtworks.com/insights/blog/mockists-are-dead-long-live-classicists

www.thoughtworks.com/insights/blog/write-better-tests-5-steps

Obrigado

top related