2017-06-16 45 views
1

我想检查块是否在我的函数中使用rspec调用。下面是我的代码:如何检查块使用rspec调用

class SP 
    def speak(options={},&block) 
    puts "speak called" 
    block.call() 
    rescue ZeroDivisionError => e 
    end 
end 




describe SP do 
it "testing speak functionality can receive a block" do 
    sp = SP.new 
    def test_func 
     a = 1 
    end 
    sp_mock = double(sp) 
    expect(sp_mock).to receive(:speak).with(test_func) 
    sp.speak(test_func) 
end 
end 

下面是我的错误:

SP testing speak functionality can receive a block 
    Failure/Error: block.call() 

    NoMethodError: 
     undefined method `call' for nil:NilClass 
    # ./test.rb:9:in `speak' 
    # ./test.rb:25:in `block (2 levels) in <top (required)>' 

能否请你帮忙。我花了很多时间。

回答

3

你必须使用的RSpec的yield matcher之一:

describe SP do 
    it "testing speak functionality can receive a block" do 
    sp = SP.new 
    expect { |b| sp.speak(&b) }.to yield_control 
    end 
end 
2

我觉得斯特凡提供了最好的答案。不过,我想指出的是,您应该测试代码的行为而不是实现细节。

describe SP do 
    it "testing speak functionality can receive a block" do 
    sp = SP.new 
    called = false 
    test_func = ->() { called = true } 

    sp.speak(&test_func) 

    expect(called).to eql(true) 
    end 
end 
+0

这就是'yield_control'的作用,不是吗? – Stefan

+0

@Stefan这取决于你真正想测试的东西。在这种情况下'.yield_with_no_args'将是最具体的测试。但是由于'SP#speak'的行为取决于传递的块,因此您应该也覆盖这些情况。在测试设置中,传递的块应该“引发ZeroDivisionError”。 –