很簡單的例子:測試用一個單一個軌道模型的驗證方法
型號:
require 'inventory'
class CustomerOrder < ActiveRecord::Base
validates_presence_of :name
validate :must_have_at_least_one_item, :items_must_exist
before_save :convert_to_internal_items
attr_accessor :items
after_initialize do
#convert the internal_items string into an array
if internal_items
self.items ||= self.internal_items.split(',').collect { |x| x.to_i }
else
# only clobber it if it hasn't been set yet, like in the constructor
self.items ||= []
end
end
private
def convert_to_internal_items
#TODO: convert the items array into a string
self.internal_items = self.items.join(',')
end
def must_have_at_least_one_item
self.items.size >= 1
end
def items_must_exist
self.items.all? do |item|
Inventory.item_exists?(item)
end
end
end
庫存是一個單應提供接入到另一個服務在那裏。
class Inventory
def self.item_exists?(item_id)
# TODO: pretend real code exists here
# MORE CLARITY: this code should be replaced by the mock, because the actual
# inventory service cannot be reached during testing.
end
end
現在服務不存在,所以我需要爲我的測試嘲笑這種方法。我很難以正確的方式做這個(tm)。我想讓它可以以某種方式配置,這樣我就可以在測試過程中進行模擬,但是在真實世界中運行普通代碼。
有可能是我沒有正確包裹我的頭。
編輯:更清楚:我需要模擬模型的驗證方法內的庫存類。最終,這會與目前不存在的服務進行對話。所以對於我的測試,我需要嘲笑它,彷彿我所說的服務真的存在。很抱歉的混亂:(
這裏是想什麼我有在規格:
describe CustomerOrder do
it "should not accept valid inventory items" do
#magical mocking that makes Inventory.item_exists? return what I want
magic.should_receive(:item_exists?).with(1).and_return(false)
magic.should_receive(:item_exists?).with(2).and_return(true)
co = CustomerOrder.new(:name => "foobar", :items => [1,2]
co.should_not be_valid
end
it "should be valid with valid inventory items" do
#magical mocking that makes Inventory.item_exists? return what I want
magic.should_receive(:item_exists?).with(3).and_return(true)
magic.should_receive(:item_exists?).with(4).and_return(true)
co = CustomerOrder.new(:name => "foobar", :items => [3,4]
co.should be_valid
end
end
使用Rails 3.0.3,rspec的2和黃瓜當然,只有部分的RSpec事項
。
我不明白你的意思......必須是漫長的夜晚,不是嗎?嘗試編輯一下,然後給出一個標誌,它有明確的問題。 – m4risU 2011-01-25 00:14:08