2013-10-26 48 views
1

我在閱讀「使用Rails進行敏捷Web開發」,我無法理解單元測試。Ruby on Rails:編寫正確的單元測試

有這樣定義的模型:

class Product < ActiveRecord::Base 
    # ..... 
    validates :price, numericality: {greater_than_or_equal_to: 0.01} 
    # ..... 
end 

而且測試:

test "product price must be positive" do 
    product = Product.new(
     title: "my title", 
     description: "yyy", 
     image_url: "zzz.jpg", 
    ) 

    product.price = -1 
    assert product.invalid? 
    assert_equal ["must be greater than or equal to 0.01"], 
     product.errors[:price] 

    product.price = 0 
    assert product.invalid? 
    assert_equal ["must be greater than or equal to 0.01"], 
     product.errors[:price] 

    product.price = 1 
    assert product.valid? 

    end 

爲什麼我們需要這樣的:

assert_equal ["must be greater than or equal to 0.01"], 
     product.errors[:price] 

爲什麼比較錯誤訊息?而不是寫這樣的測試:

product.price = -1 
assert product.invalid?, "must be greater than or equal to 0.01" 

product.price = 0 
assert product.invalid?, "must be greater than or equal to 0.01" 

回答

1

據我所知,本書的作者確實想驗證錯誤信息是他預期的錯誤信息。

在我看來,硬編碼錯誤信息是一個非常糟糕的主意,因爲它可能會在下一個框架版本中更改。

+0

硬編碼錯誤信息僅供初學者快速掌握。在同一章節(7. TASK B :)中,作者已將此硬編碼消息更改爲:assert_equal [I18n.translate('errors.messages.taken')], product.errors [:title] –

0

object.errors是一個空白的散列。當保存/更新加載ActiveModel一個例子,如果驗證失敗,錯誤將被添加到特定的密鑰相匹配的屬性,如:

{ price: "must be...", name: "can't be blank", ...}. 

在這種情況下,它的「價格」,這驗證失敗。所以錯誤對象是

{ price: "must be greater than or equal to 0.01"} 

要訪問消息字符串。您需要將失敗的屬性作爲關鍵字,如errors[:price]

+0

是的,我知道'object.errors'哈希值。我不明白爲什麼我們需要通過'assert'比較它中的值?相反,我們應該設置一些無效值並檢查對象是否無效。如果它是有效的,那麼錯誤信息將被添加到'object.errors',我不明白爲什麼我們需要在這裏檢查這個錯誤文本(無論如何,這個文本將在測試階段被回顯) –

+0

@DmitryFrank,判斷一個對象是否無效,唯一的方法是檢查它是否有錯誤屬性,這個屬性不是空白:) –

+0

看看這裏的源代碼:http://apidock.com/rails/v3.2.13/ActiveModel /驗證/ run_validations!這是「有效?」和「無效?」方法的依賴。 –