如何通过期望将块传递给RSpec

时间:2013-05-15 11:02:16

标签: rspec2 rspec-rails

说我有课

Class Foo < ActiveRecord::Base

  def set_publication
      Publication.new do |publication|
        publication.owner_type = 'Foo'
        publication.owner_id   =  123
      end
      return 'something else'
  end
end

问题:如何测试发布新实例将接收的块

describe Foo, 'set_publication' do
  let(:foo){ Foo.new }

  it do
    Publication.should_recive(:new).with( ??????? ).and_return( double(:something) )
    foo.set_publication
  end
end

当然这只是一个非常复杂的功能的例子,我不能像这样使用哈希参数

Class Foo < ActiveRecord::Base

  def set_publication
     Publication.new owner_type: 'Foo', owner_id: 123         
     return 'something else'
  end
end

并像这样测试

describe Foo, 'set_publication' do
  let(:foo){ Foo.new }

  it do
    Publication.should_recive(:new).with( owner_type: "Foo", owner_id: 123 ).and_return( double(:something) )
    foo.set_publication
  end
end

谢谢


更新:似乎有点不清楚我在这里问的是什么,所以:

我正在寻找方法来确保使用一组参数显式调用Publication.new,在本例中为一个块

所以我想这样的事情

Publication.should_receive(:new).with(&block) # example

其中块参数owner_type =='foo'和owner_id == 123

2 个答案:

答案 0 :(得分:1)

您可以使用and_yield来完成此任务。

class Foo
  def set_publication
    Publication.new do |publication|
      publication.owner_type = 'Foo'
      publication.owner_id   =  123
    end
    return 'something else'
  end
end

class Publication
  attr_accessor :owner_id, :owner_type

  def initialize
    yield self if block_given?
  end
end

和规范

describe Foo do 
  let(:foo) { Foo.new }
  let!(:publication) { Publication.new }

  it do
    Publication.should_receive(:new).and_yield(publication)

    foo.set_publication

    publication.owner_type.should eq 'Foo'
    publication.owner_id.should eq 123
  end
end

答案 1 :(得分:0)

我唯一可能的(和工作)解决方案是:

Class Foo < ActiveRecord::Base

  def set_publication
      Publication.new &publication_block_params(123)
      return 'something else'
  end

  def publication_block_params(some_id)
    Proc.new do |publication|
      publication.owner_type = 'Foo'
      publication.owner_id   =  some_id # could be self.id but let's keep it this way 
    end
  end

end

和规范

describe Foo, 'set_publication' do
  let(:foo){ Foo.new }
  let(:my_block){ Proc.new {} }

  it do
    foo.should_receive(:publication_block_params).with(123).and_return(my_block)
    Publication.should_receive(:new).with( &my_block ).and_return( double(:something) )

    foo.set_publication
  end
end

并且单独创建发布块参数的规范

describe Foo, 'publication_block_params' do
  let(:foo){ Foo.new }

  it do      
    publication = Publication.new &foo.publication_block_params(123)
    publication.owner_id.should   be 123
    publication.owner_type.should be 'Foo'
  end
end