以這個程式來說,我們要把「課程上架」,課程上架以後,系統會送一封 onboarding 信給開課教師。
class Course belongs_to :user def published? published_at.present? end def publish! user.send_welcome_email!(self) update_column(:published_at, Time.now) end end
class User < ActiveRecord::Base has_many :courses def send_welcome_email!(course) UserMailer.send_course_welcome(course) end end
但是下面這個測試,我們在這裡測試的狀況,我們根本不在乎「信是否有沒有被送給開課教師」,我們在乎的是:呼叫 publish!
後,是否課程真的已經會被上架。
所以我們就會用 allow(course.user).to receive(:send_welcome_email!)
把 send_welcome_email!
這件事 stub 掉,讓它 return nil,這樣就不會呼叫 UserMailer 了。
何況,我們可能也還沒時間開發 UserMailer 內的東西。
describe "#publish!" do let(:user) { FactoryGirl.create(:user) } let(:course) { FactoryGirl.create(:course, :user => user ) } it "will be publsihed" do allow(course.user).to receive(:send_welcome_email!) course.publish! expect(course).to be_published end end
course.stub(:send_welcome_email!)
,但這寫法造成一些敘述語法問題,所以 RSpec 3 改成 allow + receive stub
與 mock
語法造成一些很大的語法與觀念問題。RSpec 3 改的清楚不少...