Ruby 如何使用rspec测试dslapi方法
我想测试一个方法是否接收一个块。。。但是我的rspec存根返回Ruby 如何使用rspec测试dslapi方法,ruby,rspec,Ruby,Rspec,我想测试一个方法是否接收一个块。。。但是我的rspec存根返回(无参数) 这里有一个人为的例子 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
(无参数)
这里有一个人为的例子
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)
bar.rb
我不认为有任何方法可以验证在事实发生后是否通过了块,但如果使用正常的预执行预期,可以按如下方式检查它:
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
如果您不介意实际屈服于块,那么可以使用。和_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
为了测试一个块是否被调用,而不必运行它,并查看收益率是否失败,我决定重新打开这个类并利用一个类变量。这是一个临时的解决方法,因为(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
真的。。。这是因为它是一个人为的例子。。。。试想一下这个测试并不是毫无意义的:)对不起,我把这个问题误读为使用了
应该接收
而不是应该接收
。我将更新我的答案。。并且_yield
有效,但我想阻止运行该过程。我决定使用stubingFoo.stub
将该块分配给一个类变量,我可以检查该类变量是否为proc的实例。@brewster您是否介意发布您最终完成的操作?我不明白,我想知道。我正在考虑为RSpec生成一个PR,以引入一个with_block
方法,该方法将在不调用块的情况下检查块的存在,我想了解任何替代方法。刚刚看到您的答复。。。我刚刚添加了我的变通解决方案作为另一个答案。向rspec提交PR完全合适。如果需要的话,我可以想出一个非人为的例子来说明这实际上是如何有用的。谢谢。另一种方法见我的更新答案。
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
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
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