instance_doubles當我在訊息鏈中間需要更多粒度時,我一直在撰寫測驗來代替訊息鏈。但是,我想知道我是否在以艱難的方式做事。
這是我要測驗的方法:
def run_produceable_job
# Delete any jobs that exist, but haven't started, in favor of this new job
Delayed::Job.where(queue: 'produceable', locked_at: nil).delete_all
ProduceableJob.perform_later
end
對于Delayed::Job呼叫,重要的是我檢查佇列名稱是否符合預期。我還想確保 Delayed::Job.delete_all最后收到
我想做這樣的事情:
expect(Delayed::Job).to receive(:where).with(queue: 'produceable', locked_at: nil).and_then_receive(:delete_all)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
RSpec 是否為接收提供某種鏈接?我瀏覽了檔案,但找不到任何專門討論添加多個接收的內容。
或者我將不得不這樣做很長的路要走?
ar_relation = instance_double ActiveRecord::Relation
allow(Delayed::Job).to receive(:where).with(queue: 'produceable', locked_at: nil).and_return(ar_relation)
allow(ar_relation).to receive(:delete_all)
expect(Delayed::Job).to receive(:where).with(queue: 'produceable', locked_at: nil)
expect(ar_relation).to receive(:delete_all)
uj5u.com熱心網友回復:
恕我直言,你必須走很長的路。沒有更簡短的方式來描述它。
無論如何,我建議您過度考慮您的測驗策略。目前,您測驗是否呼叫了非常具體的方法組合,但如果這些方法呼叫實際上正在執行您希望它們執行的操作,則不會。
相反,我會創建一個應該洗掉的示例記錄(可能還有一些不應該洗掉的記錄),然后運行該作業并隨后測驗僅洗掉了預期的記錄。
例如像這樣:
let!(:record_to_be_deleted) { Delayed::Job.create!(queue: 'produceable', locked_at: nil) }
let!(:records_to_stay) do
[
Delayed::Job.create!(queue: 'produceable', locked_at: Time.current),
Delayed::Job.create!(queue: 'default', locked_at: nil)
]
end
it "should remove only expected records" do
expect {
instance.run_produceable_job
}.to chance { DelayedD::Job.count }.from(3).to(2)
expect {
record_to_be_deleted.reload
}.to raise_error(ActiveRecord::RecordNotFound)
end
經驗法則是測驗預期的結果,而不是具體的實作。因為實作可能會改變,會被重構或在未來的版本中可能會中斷。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/366656.html
