我想测试一个方法接收一个块...但我的rspec存根返回(no args)
。
这是一个人为的例子......
class Foo
def self.bar &block
end
end
describe Foo do
before do
Foo.stub(:bar)
Foo.bar { 'foo'}
end
it 'should' do
expect(Foo).to have_received(:bar).with(kind_of(Proc))
end
end
导致......
1) Foo should
Failure/Error: expect(Foo).to have_received(:bar).with(kind_of(Proc))
<Foo (class)> received :bar with unexpected arguments
expected: (#<RSpec::Mocks::ArgumentMatchers::KindOf:0x1022a7b20 @klass=Proc>)
got: (no args)
修改 的
这是Peter实施解决方案的一个毫无意义的例子......
foo.rb
class Foo
def self.setup &block
@setup ||= block
end
def setup
instance_eval &self.class.setup
end
end
bar.rb
# DSL designed class
class Bar < Foo
setup do
# setup Bar instances here
end
end
bar_spec.rb
# Need to make sure DSL classes are correctly implemented
describe Bar do
after do
load 'bar'
end
it 'should define .setup' do
expect(Bar).to receive(:setup){ |&block| expect(block).to be_a(Proc) }
end
end
答案 0 :(得分:2)
我不相信有任何方法可以验证事件后是否传递了一个块,但如果您使用正常的执行前期望值,则可以按如下方式检查:
class Foo
def self.bar &block
puts 'DO NOT RUN'
end
end
describe 'Foo#bar' do
it 'should confirm a block is passed' do
expect(Foo).to receive(:bar) {|&block| expect(block).to be_a(Proc)}
Foo.bar {}
end
it 'should confirm a block is not passed' do
expect(Foo).to receive(:bar) {|&block| expect(block).to be_nil}
Foo.bar
end
end
如果你不介意实际屈服于该块,那么你可以使用.and_yield
,如果一个块不存在,这将产生一个期望错误。
class Foo
def self.bar &block
end
end
describe Foo do
before do
Foo.stub(:bar), y
end
it 'should' do
expect(Foo).to receive(:bar).and_yield
Foo.bar {}
end
end
答案 1 :(得分:0)
为了测试一个块被调用而不必运行它并查看yield是否失败,我决定重新打开该类并利用类var。这是一个临时的解决方法,因为(IMO)rspec应该负责此功能。
class Foo
def self.bar &block
puts 'DO NOT RUN'
end
end
describe Foo do
before do
class Foo
def self.bar &block
Foo.send(:class_variable_set, :@@bar_val, block)
end
Foo.bar {} # this line is dynamic in my real specs :)
end
end
after :all do
load 'foo' # to revert back to the original class
end
it 'should' do
expect(Foo.send(:class_variable_get, :@@bar_val)).to be_a Proc
end
end