2011-09-24 16 views
66

मैंने रेल में टीडीडी के साथ अपनी यात्रा शुरू कर दी है और मॉडल सत्यापन के परीक्षणों के संबंध में एक छोटी सी समस्या में भाग लिया है जिसे मुझे समाधान नहीं मिल रहा है। के मैं एक उपयोगकर्ता मॉडल है मान लीजिए,रेल 3.1, आरएसपीसी: परीक्षण मॉडल सत्यापन

class User < ActiveRecord::Base 
    validates :username, :presence => true 
end 

और एक साधारण परीक्षण

it "should require a username" do 
    User.new(:username => "").should_not be_valid 
end 

यह सही ढंग से उपस्थिति मान्यता का परीक्षण करती है, लेकिन मैं अधिक विशिष्ट क्या चाहते हैं? उदाहरण के लिए, त्रुटियों पर परीक्षण full_messages आपत्ति ..

it "should require a username" do 
    user = User.create(:username => "") 
    user.errors[:username].should ~= /can't be blank/ 
end 

प्रारंभिक प्रयास (should_not be_valid का प्रयोग करके) के बारे में मेरी चिंता का विषय है कि RSpec एक वर्णनात्मक त्रुटि संदेश का उत्पादन नहीं होगा। यह बस कहता है "झूठी वापसी के लिए वैध उम्मीद है, सच हो गया।" हालांकि, दूसरे परीक्षण उदाहरण में मामूली कमी है: यह त्रुटियों की वस्तु को प्राप्त करने के लिए नई विधि के बजाय बनाने विधि का उपयोग करता है।

मैं चाहता हूं कि मेरे परीक्षण परीक्षण के बारे में अधिक विशिष्ट हों, लेकिन साथ ही डेटाबेस को स्पर्श करने की आवश्यकता नहीं है।

किसी के पास कोई इनपुट है?

उत्तर

91

सबसे पहले मैं कहना चाहता हूं कि आपके पास एक बुरा नाम है।

दूसरा, आप पर आरओआर के साथ टीडीडी में प्रयास करने का प्रयास मैं वादा करता हूं कि एक बार जब आप जा रहे हैं तो आप वापस नहीं देखेंगे।

सरल त्वरित और गंदी समाधान इस तरह अपने परीक्षण में से प्रत्येक से पहले एक नया मान्य मॉडल उत्पन्न करने के लिए किया जाएगा:

before(:each) do 
    @user = User.new 
    @user.username = "a valid username" 
end 

लेकिन मैं क्या सुझाव है कि आप अपने सभी मॉडलों है कि एक उत्पन्न होगा के लिए अपने कारखाने स्थापित है आपके लिए स्वचालित मॉडल स्वचालित रूप से और फिर आप अलग-अलग विशेषताओं के साथ उलझन कर सकते हैं और देख सकते हैं कि आपका सत्यापन क्या है।

मूल रूप से एक बार आप अपने परीक्षण की स्थापना के लिये कुछ इस तरह दिखेगा:: मैं इस के लिए FactoryGirl का उपयोग करना चाहते

it "should have valid factory" do 
    FactoryGirl.build(:user).should be_valid 
end 

it "should require a username" do 
    FactoryGirl.build(:user, :username => "").should_not be_valid 
end 

ओह फिर और यहाँ a good railscast है यह सब बेहतर बताते हैं कि मुझसे ज्यादा:

सौभाग्य :)


अद्यतन: कारखाने महिला के लिए वाक्यविन्यास है version 3.0 के रूप में बदला हुआ। मैंने इसे प्रतिबिंबित करने के लिए अपने नमूना कोड में संशोधन किया है।

+2

धन्यवाद मैथ्यू। क्या त्रुटि का करीब आने का कोई तरीका है जिसे मैं परीक्षण करने की कोशिश कर रहा हूं? X.should_not be_valid मेरे लिए इतना सामान्य प्रतीत होता है, और कौन जानता है कि सड़क के नीचे कुछ और रिकॉर्ड अवैध हो जाएगा। यह परीक्षण गलत जगह पर असफल हो जाएगा। वैसे, मुझे लगता है कि मैंने आपका जवाब स्वीकार कर लिया है। क्या मैं नहीं – Feech

+7

ठीक है, इसलिए यही कारण है कि मैं कारखानों के लिए बहस करता हूं। आप वैध उपयोगकर्ता को एक ही स्थान पर एक बार उत्पादित करने के लिए कोड लिखते हैं और फिर आप यह सुनिश्चित करने के लिए एक परीक्षण लिखते हैं कि यह सभी व्यक्तिगत परीक्षणों से पहले मान्य है जो सुनिश्चित करते हैं कि आप इसे अमान्य कर सकते हैं। इस तरह यदि किसी कारण से आप अपना मॉडल बदलते हैं तो कारखाना लंबे समय तक वैध उपयोगकर्ता को 'फैक्ट्री.बिल्ड (: उपयोगकर्ता) बनाता है। Should be_valid' परीक्षण विफल हो जाएगा और आपको पता चलेगा कि आपको अपने कारखाने को अपडेट करना होगा ... इसे प्राप्त करें ? (और हाँ आपने मेरा 7 उत्तर स्वीकार किया) – Matthew

+0

बिल्कुल सही स्पष्टीकरण। एक बार फिर धन्यवाद। – Feech

41

मॉडल सत्यापन (और बहुत अधिक सक्रिय रिकॉर्ड) का परीक्षण करने का एक आसान तरीका shoulda या remarkable जैसे मणि का उपयोग करना है।

वे इस प्रकार परीक्षण करने की अनुमति देगा:

describe User 

    it { should validate_presence_of :name } 

end 
+1

यह जांचना अच्छा होता है कि आपके पास मॉडल में एसोसिएशन हैं, लेकिन इस बात से अवगत रहें कि यह वास्तव में किसी उपयोगकर्ता को नाम के बिना बनाने की कोशिश नहीं करेगा और इसकी वैधता – brafales

+3

@brafales वास्तव में नहीं, वास्तव में यह है कि यह वास्तव में क्या करना चाहिए: यह ऑब्जेक्ट को रिक्त नाम से बनाने का प्रयास करेगा, और इसे एक त्रुटि देनी चाहिए। – nathanvda

+2

आप सही हैं, ऐसा लगता है जैसे मैंने कोड गलत किया है https://github.com/thoughtbot/shoulda-matchers/blob/master/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb – brafales

0

मैं पारंपरिक रूप से संभाला है सुविधा या अनुरोध चश्मा में त्रुटि सामग्री चश्मा।तो, उदाहरण के लिए, मैं एक ऐसी ही कल्पना जो मैं नीचे गाढ़ा करता हूँ है:

फ़ीचर युक्ति उदाहरण

before(:each) { visit_order_path } 

scenario 'with invalid (empty) description' , :js => :true do 

    add_empty_task         #this line is defined in my spec_helper 

    expect(page).to have_content("can't be blank") 

तो फिर, मैं अपने मॉडल कल्पना परीक्षण है कि क्या कुछ वैध है है, लेकिन फिर मेरे फीचर स्पेक जो त्रुटि संदेश के सटीक आउटपुट का परीक्षण करता है। एफवाईआई, इन फीचर चश्मे को कैपिबरा की आवश्यकता होती है जिसे here मिल सकता है।

15

इस प्रयास करें:

it "should require a username" do 
    user = User.create(:username => "") 
    user.valid? 
    user.errors.should have_key(:username) 
end 
+0

यह मेरा पसंदीदा, बहुत ठोस है, कुंजी जांचता है, न कि संदेश – ecoologic

+3

आप डीबी –

+0

@TaufiqMuhammadi 'new' को मारने से बचने के लिए केवल उपयोगकर्ता = उपयोगकर्ता.न्यू (: उपयोगकर्ता नाम =>" ") का उपयोग कर सकते हैं, उदाहरण के लिए डीबी स्तर सत्यापन को हिट नहीं करेंगे एक विशिष्टता सूचकांक बाधा। – mnort9

2
नए संस्करण rspec में

, आप, उम्मीद का उपयोग करना चाहिए बजाय चाहिए अन्यथा आप मिल जाएगा चेतावनी:

it "should have valid factory" do 
    expect(FactoryGirl.build(:user)).to be_valid 
end 

it "should require a username" do 
    expect(FactoryGirl.build(:user, :username => "")).not_to be_valid 
end 
+0

आपको उदाहरण नामों में मौजूदा तनख्वाह क्रियाओं का भी उपयोग करना चाहिए। उपरोक्त को फिर से लिखा जा सकता है क्योंकि "" वैध कारखाना है "और' "उपयोगकर्ता नाम की आवश्यकता है"। – BrunoFacca

0

तरह @nathanvda कहा, मैं का लाभ ले जाएगा थॉटबॉट का Shoulda Matchers मणि। उस रॉकिंग के साथ, आप उपस्थिति के परीक्षण के साथ-साथ किसी भी कस्टम त्रुटि संदेश के रूप में निम्न परीक्षण में अपना परीक्षण लिख सकते हैं।

RSpec.describe User do 

    describe 'User validations' do 
    let(:message) { "I pitty da foo who dont enter a name" } 

    it 'validates presence and message' do 
    is_expected.to validate_presence_of(:name). 
     with_message message 
    end 

    # shorthand syntax: 
    it { is_expected.to validate_presence_of(:name).with_message message } 
    end 

end 
संबंधित मुद्दे