over 8 years ago

以這個程式來說,我們要把「課程上架」,課程上架以後,系統會送一封 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
  • 備註: 在 RSpec 2.x 版,你可以直接這樣寫 course.stub(:send_welcome_email!),但這寫法造成一些敘述語法問題,所以 RSpec 3 改成 allow + receive
  • 備註: 在 RSpec 2.x 的 stubmock 語法造成一些很大的語法與觀念問題。RSpec 3 改的清楚不少...
← [RSpec] 進階測試系列概念 - Part 2 Stub V.S. Mock [RSpec] 進階測試系列概念 - Part 4 使用 double ( mock objects ) →
 
comments powered by Disqus