如何用rspec測試這樣的代碼?如何測試ActiveRecord創建塊內的行爲?
Foo.create! do |foo|
foo.description = "thing"
end
我不想測試被創建的對象 - 我想測試是否正確的方法被正確的對象調用。等效於測試這一點:
Foo.create!(description: "thing")
與此:
Foo.should_receive(:create!).with(description: "thing")
如何用rspec測試這樣的代碼?如何測試ActiveRecord創建塊內的行爲?
Foo.create! do |foo|
foo.description = "thing"
end
我不想測試被創建的對象 - 我想測試是否正確的方法被正確的對象調用。等效於測試這一點:
Foo.create!(description: "thing")
與此:
Foo.should_receive(:create!).with(description: "thing")
這是你以後在做什麼?
it "sets the description" do
f = double
Foo.should_receive(:create!).and_yield(f)
f.should_receive(:description=).with("thing")
Something.method_to_test
end
Foo.count.should == 1
Foo.first.description.should == 'thing'
但我不想測試基礎的持久性行爲 - 我想測試代碼是否將正確的對象設置到正確的位置。我現在給我的問題添加了更多細節。 –
「我想測試正確的對象是否調用了正確的方法。」 你可以通過指定結果狀態來做到這一點,就像@ antiqe的例子。您認爲通過指定使用'description ='還是'write_attribute(:description,「value」)'或任何其他可供選擇的替代方法,您會獲得哪些好處? –
@DavidChelimsky的目標是不測試AR創建的持久性質量。我知道每個我正在測試的方法都能正常工作,所以爲了測試使用它們的函數,我可以測試它們是否被調用。我知道這並不是那麼漂亮,而新的熱度似乎永遠不會做控制器規格的原因 - 只有響應和/或整合。但無論如何回到你的觀點 - 是的,這是真的,兩種方法都會有相同的行爲,所以我應該測試他們的結果。所以我想FG build_stubbed並測試結果值可能是一個很好的整體解決方案。思考? –
下面是一個組合方法,它將@ antiqe和@Fitzsimmons的答案中的最佳值合併在一起。儘管如此,它明顯更加冗長。
這個想法是模仿Foo.create,其行爲更像AR :: Base.create。弗里斯特,我們定義了一個輔助類:
class Creator
def initialize(stub)
@stub = stub
end
def create(attributes={}, &blk)
attributes.each do |attr, value|
@stub.public_send("#{attr}=", value)
end
blk.call @stub if blk
@stub
end
end
,然後我們可以在我們的規格使用它:
it "sets the description" do
f = stub_model(Foo)
stub_const("Foo", Creator.new(f))
Something.method_to_test
f.description.should == "thing"
end
你也可以使用FactoryGirl.build_stubbed
代替stub_model
。但是,您不能使用mock_model
,mock
或double
,因爲您再次遇到同樣的問題。
現在你的規範將通過以下任何代碼片段:
Foo.create(description: "thing")
Foo.create do |foo|
foo.descrption = "thing"
end
foo = Foo.create
foo.descrption = "thing"
的寶貴意見!
有些東西不需要測試,除非描述是自定義方法,或者這是學術興趣? – antiqe
我需要確保我的客戶端代碼將正確的對象分配給正確的屬性 –