Rails

2013-05-13 17 views
69

bir Endişe Nasıl Test Edilir full_name yöntemi olan benim Rails 4 uygulamada bir Personable endişe var göz önüne alındığında, ben bu RSpec kullanarak test hakkında nasıl giderdim?Rails

endişeler/personable.rb Aldığım haberlere yanıt olarak

module Personable 
    extend ActiveSupport::Concern 

    def full_name 
    "#{first_name} #{last_name}" 
    end 
end 
+0

Hangi sınama çerçevesi kullanıyorsunuz? Ayrıca, hatırlanabilir ki sadece normal bir Ruby modülüdür. Diğer karışımları test edeceğiniz gibi test edin. –

+0

"ActiveSupport :: Concern" Rails'den çıkarılmadı mı? Biraz önce gittiğini düşündüm. – Russell

+0

@LeeJarvis w/FactoryGirl –

cevap

118

Bulduğunuz yöntem, biraz işlevselliği test etmek için işe yarayacaktır, ancak oldukça kırılgan görünüyor — kukla sınıfınız (aslında çözümünüzde sadece bir Struct), include'un endişeleriniz gibi gerçek bir sınıf gibi davranabilir veya davranmayabilir. Ek olarak, model endişelerini test etmeye çalışıyorsanız, veritabanını buna göre ayarlamadığınız sürece nesnelerin geçerliliğini sınama veya ActiveRecord geri çağırmalarını çağırma gibi şeyler yapamayacaksınız (çünkü kukla sınıfınızın bir veritabanı tablosu desteğine sahip olmayacağı için) o). Ayrıca, sadece endişeyi test etmekle kalmayacak, aynı zamanda endişe davranışlarını model özellikleriniz içinde de test edeceksiniz. Öyleyse neden iki kuşu bir taşla öldürmüyorsun? RSpec'in shared example groups'u kullanarak, endişelerinizi kullanan gerçek sınıflara (örn., Modeller) ve karşı test edebilirsiniz. Bunları kullanıldıkları her yerde test edebilirsiniz. Ve sadece testleri bir kez yazmanız ve sonra bunları endişelerinizi kullanan herhangi bir model spesifikasyonuna eklemeniz yeterlidir. Senin durumunda bu böyle görünebilir:

# app/models/concerns/personable.rb 

module Personable 
    extend ActiveSupport::Concern 

    def full_name 
    "#{first_name} #{last_name}" 
    end 
end 

# spec/concerns/personable_spec.rb 

require 'spec_helper' 

shared_examples_for "personable" do 
    let(:model) { described_class } # the class that includes the concern 

    it "has a full name" do 
    person = FactoryGirl.create(model.to_s.underscore.to_sym, first_name: "Stewart", last_name: "Home") 
    expect(person.full_name).to eq("Stewart Home") 
    end 
end 

# spec/models/master_spec.rb 

require 'spec_helper' 
require Rails.root.join "spec/concerns/personable_spec.rb" 

describe Master do 
    it_behaves_like "personable" 
end 

# spec/models/apprentice_spec.rb 

require 'spec_helper' 

describe Apprentice do 
    it_behaves_like "personable" 
end 

Bir AR nesnenin daha azı sadece 'kazandı nerede, AR geri aramalar çağırma gibi endişe şeyler yapmaya başlarsa daha da belirgin hale bu yaklaşımın avantajları Yap.

+1

Bunun bir dezavantajı 'parallel_tests' yavaşlatacak olmasıdır güzel görünüyor. "Shared_examples_for" ve "it_behaves_like" kullanmak yerine ayrı testlere sahip olmak daha iyi olacak. Bunu https://github.com/grosser/parallel_tests/issues/168 başına doğru olduğundan emin değilim –

+4

@ArtemKalinchuk 'parallel_tests' dosya başına dayanır, bu yüzden paylaşılan örnekler yavaşla olmamalıdır. Doğru şekilde gruplanmış paylaşılan davranışların, test hızının konduğunu da iddia ediyorum. –

+8

'' endişeleri' 'dizinini 'spec_helper.rb' https://github.com/rspec/rspec-core/issues/407#issuecomment-1409871 – Ziggy

37

, burada ben (herkes iyileştirmeler varsa onları göndermek için çekinmeyin) yapıyor sona buydu :

spec/kaygılar/personable_spec.rb

require 'spec_helper' 

describe Personable do 

    let (:test_class) { Struct.new(:first_name, :last_name) { include Personable } } 
    let (:personable) { test_class.new("Stewart", "Home") } 

    it "has a full_name" do 
    personable.full_name.should == "#{personable.first_name} #{personable.last_name}" 
    end 

end 
+1

Evet, bu, eğer 'Person' (Gerçek Kişi) denen gerçek bir sınıfı test ederse diğer testleri de kıracaktır. Düzeltmek için düzenlerim. – Russell

+0

Bu işe yaramıyor. Bana şu hatayı verir: # tanımsız yöntem "full_name" için # " –

+0

" Genişletmek yerine "Userable" ı dahil etmeyi deneyin. Cevabı güncelleyeceğim. – Russell

3

Başka bir düşünce, bu gibi şeyleri test etmek için with_model gem kullanmaktır. Bir endişeyi kendim denemek için bakıyordum ve pg_search gem doing this'u görmüştü. Bireysel modellerde test yapmaktan çok daha iyi gözüküyor, çünkü bunlar değişebilir ve sizin özelliklerinde ihtiyaç duyacağınız şeyleri tanımlamak güzel.

+0

Teşekkürler. "With_model" görmemiştim – Subimage

+0

Evet, bu harika. Teşekkürler :) –

+0

Ben with_model gibi hissediyorum hala Ryan Demiryolları yapıyor olsaydı Ryan Bates işaret etmişti. Adamı o adamı özlüyorum. – IAmNaN