RSpec,如何在模块内部进行初始化测试

时间:2012-07-15 09:52:52

标签: ruby-on-rails rspec

我有这个模块:

module TicketsPresenters

    class ShowPresenter
      def initialize(ticket_or_id = nil)
        unless ticket_or_id.nil?
          if ticket_or_id.is_a?(Ticket)
            @ticket = ticket_or_id
          else
            @ticket = Ticket.find(ticket_or_id)
          end
      end
    end

end

当我传递整数或直接传递对象实例时,我想测试initialize()方法是否正确设置了对象。

1 个答案:

答案 0 :(得分:2)

可能有十几种方法可以回答这个问题,但我会给你更喜欢的RSpec格式。

以下假设您的ShowPresenter类中有一个读取器方法(即attr_reader :ticket)。它还假设您使用有效参数创建Ticket对象,以便保存它。

describe TicketsPresenters::ShowPresenter do
  context '#initialize' do
    let!(:ticket) { Ticket.create!(...) }

    context 'with an id' do
      subject { TicketsPresenters::ShowPresenter.new(ticket.id) }
      its(:ticket) { should == ticket }
    end

    context 'with a Ticket object' do
      subject { TicketsPresenters::ShowPresenter.new(ticket) }
      its(:ticket) { should == ticket }
    end

    context 'with nothing' do
      subject { TicketsPresenters::ShowPresenter.new }
      its(:ticket) { should be_nil }
    end
  end
end

注意:我是FactoryGirl的粉丝所以我个人更喜欢使用Factory.create(:ticket)而不是Ticket.create!(...),因为它允许您在一个地方定义有效的Ticket对象而且您不会如果该定义发生变化,则需要在所有测试中更新它。

人们采取的另一个测试立场是根本不使用数据库持久性。这可能不是我建议Ruby或RSpec新手的概念,因为它有点难以解释并且需要更多的OOP知识。好处是它消除了数据库依赖性,测试更快,更孤立。

describe TicketsPresenters::ShowPresenter do
  context '#initialize' do
    let(:ticket) { mock(:ticket, id: 1) }

    before do
      ticket.stub(:is_a?).with(Ticket) { true }
      Ticket.stub(:find).with(ticket.id) { ticket }
    end

    context 'with an id' do
      subject { TicketsPresenters::ShowPresenter.new(ticket.id) }
      its(:ticket) { should == ticket }
    end

    context 'with a Ticket object' do
      subject { TicketsPresenters::ShowPresenter.new(ticket) }
      its(:ticket) { should == ticket }
    end

    context 'with nothing' do
      subject { TicketsPresenters::ShowPresenter.new }
      its(:ticket) { should be_nil }
    end
  end
end