這是一個很好的做法通常有以下幾個原因:
從視圖的隔離點:所述控制器的職責是處理傳入請求,並相應地觸發動作。在我們的案例中,這些行動是:創建一個新的工作,併發佈一個新的職位,如果一切正常。 (請注意我們的控制器並不需要知道如何張貼到FB)
所以,想象下面的控制器操作:
def create
job = Job.new job_params
if job.save
FacebookService.post_job job
...
else
...
end
end
我會測試它想:
class JobsControllerTest < ActionController::TestCase
test "should create a job and issue new FB post" do
job_params = { title: "Job title" }
# We expect the post_job method will be called on the FacebookService class or module, and we replace the original implementation with an 'empty/mock' method that does nothing
FacebookService.expects :post_job
post :create, job_params
assert_equal(Job.count, 1) # or similar
assert_response :created
end
end
的其他好處是:FacebookService.post_job
可能需要很長時間,並且可能需要互聯網接入等,我們不希望我們的測試等待這些,特別是如果我們有CI。
最後,我會在FacebookService測試中測試真實的FB發佈,並可能會列出其他一些方法,以防止在測試運行時每次都發布FB(它需要時間,Internet,FB帳戶......) )。
在測試運行期間,您通常不會將數據發送到Facebook。因此你嘲笑Facebook電話。如果你的'Job'有一個'notify_facebook'方法,你可以在開始job之前調用'job.stubs(:notify_facebook)'。 – sschmeck