2011-04-20 55 views
0

我是新來的鐵軌,並試圖寫我的第一個應用程序。我有一個列order_size表:整數和價格:十進制(8,5)。價格欄保存貨幣價格,因此需要非常精確,以防萬一您想知道。我正在試寫測試,以確保價格和order_size是一個正數,但無論我做什麼,他們都不會通過。簡單的Rspec測試正數不會通過

這裏是Rspec的測試

it "should require a positive order size" do 
    @attr[:order_size] = -23 
    @user.orders.create!(@attr).should_not be_valid 
end 

it "should require a positive price" do 
    @attr[:price] = -1.2908 
    @user.orders.create!(@attr).should_not be_valid 
end 

下面是Order類驗證

validates_presence_of :user_id 
    validates_numericality_of :order_size, :greater_than => 0, 
          :only_integer => true 
    validates_numericality_of :price, :greater_than => 0 

這裏的測試結果

Failures: 

    1) Order validations should require a positive order size 
    Failure/Error: @user.orders.create!(@attr).should_not be_valid 
    ActiveRecord::RecordInvalid: 
     Validation failed: Order size must be greater than 0 
    # ./spec/models/order_spec.rb:39:in `block (3 levels) in <top (required)>' 

    2) Order validations should require a positive price 
    Failure/Error: @user.orders.create!(@attr).should_not be_valid 
    ActiveRecord::RecordInvalid: 
     Validation failed: Price must be greater than 0 
    # ./spec/models/order_spec.rb:44:in `block (3 levels) in <top (required)>' 

究竟這是怎麼回事?我甚至試着運行測試,聲稱他們應該是有效的,但他們仍然失敗。任何幫助,將不勝感激。

回答

3

在我看來,由於您的驗證,創建記錄失敗,因此永遠不會得到您的斷言!正如apneadiving所指出的那樣,你想要這樣做:

order = Order.new(:order_size => -23) 
order.should_not be_valid 
+0

事實上,我也會像這樣測試它:純粹依靠'訂單'。訂單的驗證並不取決於它是否屬於'@ user'的一部分。 – nathanvda 2011-04-29 00:15:27

0

你爲什麼叫create!只需撥打new

或更改您的測試,以期望創建失敗。

+0

謝謝,修復它。但是這兩種方法基本上都是一樣的,除了'create'實際上保存了它。這就是爲什麼它不工作?它在較低的水平上失敗了,甚至沒有改變來運行測試? – 2011-04-20 22:32:12

+0

是的,ActiveRecord確實失敗了,所以你的測試。我認爲你可以使用raise_error來測試ActiveRecord失敗,但是使用new來檢查對象是否有效要好得多。 – apneadiving 2011-04-20 22:35:03

0

有幾種寫這個測試的方法。您正在使用create!方法,當它失敗時會引發異常。因此,在這種情況下,你會寫你的測試如下:

it "should require a positive order size" do 
    @attr[:order_size] = -23 
    expect { @user.orders.create!(@attr)}.to raise_error(ActiveRecord::RecordInvalid.new) 
end 

但是,實際上,事實create!確實提出了一個異常時order是無效的,是鐵軌專用的,所以我居然會測試正如@mharper所提議的那樣。