http://www.youtube.com/watch?v=bNn6M2vqxHE
1 comment | 1 point | by WazanovaNews 約7時間前 edited
「Airbnbのテスト:巻き込み力のある人がポジティブな変化をもたらす」でLou Kosakが、依存関係のないユニットテストを実現するのに参考にしたというCorey HainesのGoGaRuCo 2011での講演です。
テストの実行時間改善のために依存関係を解消するという意味では、一番読込みに時間のかかる3rd partyエンジン、つまりRailsとの関係を切り離すのが効果が大きい。
1 class ShoppingCart < ActiveRecord::Base 2 has_many :shopping_cart_products, dependent: :destroy 3 has_many :products, :through => :shopping_cart_products 4 5 def total_price 6 products.map(&:price).inject(0, &:+) 7 end 8 endのコードに対して、メソッドを切り出して、標準のRubyコードにする。
1 class ShoppingCart < ActiveRecord::Base 2 include ShoppingCartExtensions::CalculatesTotalPrice 3 4 has_many :shopping_cart_products, dependent: :destroy 5 has_many :products, :through => :shopping_cart_products 6 7 end1 module ShoppingCartExtensions 2 module CalculatesTotalPrice 3 def total_price 4 products.map(&:price).inject(0, &:+) 5 end 6 end 7 endそして、これをテスト。ダミーのカートを用意し、自分のmodelに依存するかたちにする。
1 require 'shopping_cart_extensions/calculates_total_price' 2 3 class DummyCartWithProducts 4 include ShoppingCartExtensions::CalculatesTotalPrice 5 end 6 7 describe "Calculating Total Price" do 8 it "return the total price of the products" do 9 cart = DummyCartWithProducts.new 10 products = [stub(price: 5), stub(price: 10)] 11 cart.stub(:products) { products } 12 cat.total_price,should == 15 13 end 14 endもう一つのテクニックとして、Active Recordへの依存がイヤであれば、別のオブジェクトにデリゲートすることもできる。
1 class ShoppingCart < ActiveRecord::Base 2 # include ShoppingCartExtensions::CalculatesTotalPrice 3 4 has_many :shopping_cart_products, dependent: :destroy 5 has_many :products, :through => :shopping_cart_products 6 7 def total_price 8 ShoppingCartExtensions::CalculatePrices.new.total_price(products) 9 end 10 11 end1 module ShoppingCartExtensions 2 class CalculatesPrices 3 def total_price(things_with_prices) 4 things_with_prices.map(&:price).inject(0, &:+) 5 end 6 end 7 end
#rails #ruby #テスト