ruby on rails - फैक्ट्रीगर्ल के साथ मॉडल ऐपिस में एसोसिएशनों को तेज करना-बनाम बनाम बिल्ड_स्टबैड बनाओ




ruby-on-rails unit-testing (3)

कहते हैं कि मेरे पास मॉडल User और Post , उपयोगकर्ता के पास कई पद हैं और उपयोगकर्ता के लिए एक पद है।

जब मैं Post लिए एक कल्पना लिखता हूं, तो मेरी पहली प्रवृत्ति इस तरह कुछ लिखना है:

before do
  @user = FactoryGirl.create :user
  @post = @user.posts.new(title: "Foo", content: "bar)
end

... tests for @post go here ...

लेकिन यह एक नया उपयोगकर्ता बनाने वाला है - हर एक टेस्ट के लिए डेटाबेस को मारकर - जो कुछ धीमा हो रहा है। क्या ऐसा करने का एक बेहतर तरीका है जो मेरे परीक्षणों को गति देगा और डीबी को मारने से बचने के लिए अक्सर होगा?

जैसा कि मैं इसे समझता हूं, मैं FactoryGirl.build :user उपयोग नहीं कर सकता। FactoryGirl.build :user क्योंकि, हालांकि यह डीबी प्रभावित नहीं होगा, एसोसिएशन ठीक से काम नहीं करेंगे क्योंकि @post.user पास आईडी नहीं होगा और इसलिए @post.user जीता काम नहीं है (यह nil देता है।)

मैं FactoryGirl.build_stubbed :user उपयोग कर सकता FactoryGirl.build_stubbed :user जिसने एक "फर्जी @post.user " FactoryGirl.build_stubbed :user बनाया है जिसमें आईडी है, लेकिन @post.user@post.user अभी भी शून्य देता है build दौरान क्या build_stubbed का कोई व्यावहारिक लाभ होता है जब मैं संघों से संबंधित चीजों का परीक्षण करता हूं?

मुझे लगता है कि मैं build_stubbed stub @post.user उपयोग कर सकता @post.user इसलिए यह @post.user देता है ... क्या कोई कारण यह एक बुरा विचार हो सकता है?

या क्या मुझे सिर्फ गति create और स्वीकार करने के create उपयोग करना चाहिए?

मैं सोच सकता हूं कि केवल एक अन्य वैकल्पिक विकल्प before(:all) ब्लॉक में स्थापित किया जाएगा जो एक बुरा विचार की तरह लगता है।

इन प्रकार के परीक्षणों को एक साफ, संक्षिप्त तरीके से लिखने का सबसे अच्छा तरीका क्या है जो बहुत अधिक डीबी प्रश्नों को टालते हैं?


यदि आप नहीं चाहते कि आपके परीक्षण डेटाबेस को मार रहे हों, तो यही आपको करना होगा।

before do
  @user = FactoryGirl.build_stubbed :user
  @post = FactoryGirl.build_stubbed :post
  @user.stub(:posts).and_return([@post])
  @post.stub(:user).and_return(@user)
end

नोट: before(:all) का उपयोग करते समय सावधान रहें before(:all) इसे लेनदेन में निष्पादित नहीं किया जाता है। तो before(:all) आप जो भी बनाते हैं before(:all) :) डेटाबेस में पीछे रह जाएंगे और अन्य परीक्षणों के साथ संघर्ष का कारण हो सकता है

FactoryGirl.build बारे में, यह ऑब्जेक्ट बनाता है, लेकिन एसोसिएशन बनाता है।

उदाहरण के लिए:

factory :user do
  association posts
end

FactoryGirl.build(:user) #this creates posts in the database even though you are only building the parent object(user)

संक्षिप्त जवाब

@user = FactoryGirl.build_stubbed(:user)
@post = FactoryGirl.build_stubbed(:post, :user => @user)

यह डेटाबेस को कभी भी बिना मारने के बाद @ पोस्ट। यूजर काम करेगा।

लंबा जवाब

मेरी सिफारिश को ब्लॉक से before इंतजार करना होगा जब तक आपको यह सुनिश्चित न हो कि आपको इसकी ज़रूरत है। इसके बजाय, प्रत्येक व्यक्ति की परीक्षा के लिए आवश्यक आंकड़ों का निर्माण करें और विधियों या नए कारखानों को डुप्लिकेशन निकालें, जैसा आपको मिल रहा है।

इसके अलावा, क्या आपको वास्तव में उपयोगकर्ता को हर एक परीक्षण में संदर्भित करने की ज़रूरत है? प्रत्येक परीक्षण में @user उपलब्ध होने से अन्य डेवलपर्स के मुताबिक यह हर जगह महत्वपूर्ण है।

अंत में, यह मानते हुए कि आपके डाक कारखाने में उपयोगकर्ता एसोसिएशन भी घोषित किया गया है, जब आप build_stubbed(:post) करते हैं, तो आप स्वतः काम कर रहे पोस्ट प्राप्त करेंगे।


कारखाने लड़की के दस्तावेज़ से, आप इस तरह के कारखाने में सहयोग के लिए user लिए रणनीति build पहचान कर सकते हैं:

factory :post do
  association :user, factory: :user, strategy: :build
end

ताकि आप user को बचाने के बिना एक post build सकें

post = build(:post)
post.new_record?        # => true
post.author.new_record? # => true