RSpec -- test if method called its block parameter
I usually do something like
a = 1
b.go { a = 2}
a.should == 2
RSpec -- test if block called with block defined in before
Try something like this (untested by me):
context "the node definition using block of code" do
let(:node){
node = Node.new "arg1", "arg2", node_block
# more complex stuff here
node
}
context "checking the block is called" do
let(:node_block) {
double = double("node_block")
double.should_receive("some kind of arg").and_return("something")
# this will now cause a fail if it isn't called
double
}
it "should call the block" do
node.blah()
end
end
let(:node_block) {
# some real code
}
subject { node.blah() }
it { should == 2 }
# ...
end
So that's a very shaky piece of code (you'll have to fill in the gaps as you didn't give very much to go on, and let
is obviously a lambda too, which could mean you've got to play around with it a bit) that uses let
and a double
to check it's called, and avoids using before
, which is really for side effects not setting up variables for use in the specs.
@zetetic makes a very insightful comment that you're not testing behaviour here. I'm not against using rspec for doing more unit test style stuff (guidelines are made to be broken), but you might ask how later tests will pass when using a real block of code if that block isn't being called? In a way, I'm not even sure you need to check the block is called, but only you know.
RSpec. Testing arguments of block call
It's actually really straight forward.
it "responds to data" do
DropboxApi.read_path do |batch|
expect(batch).to respond_to(:data)
end
end
it "has a count of 6" do
DropboxApi.read_path do |batch|
expect(batch.data.count).to eq(6)
end
end
And if you really want it to look more terse, like your example you can do the following.
let(:batch) {
DropboxApi.read_path do |batch|
return batch
end
}
it { expect(batch).to respond_to(:data) }
it { expect(batch.data.count).to eq(6) }
Test if a method takes a block
How can I verify if
Foobar#some_method
takes a block.
Every method in ruby takes (can take) a block. It may simply choose not to yield. So that's what you need to check, I think: if the method yielded or not.
RSpec has a number of yield expectations: https://relishapp.com/rspec/rspec-expectations/docs/built-in-matchers/yield-matchers
RSpec.describe "yield_control matcher" do
specify { expect { |b| MyClass.yield_once_with(1, &b) }.to yield_control }
specify { expect { |b| MyClass.dont_yield(&b) }.not_to yield_control }
specify { expect { |b| MyClass.yield_twice_with(1, &b) }.to yield_control.twice }
specify { expect { |b| MyClass.yield_twice_with(1, &b) }.to yield_control.exactly(2).times }
specify { expect { |b| MyClass.yield_twice_with(1, &b) }.to yield_control.at_least(1) }
specify { expect { |b| MyClass.yield_twice_with(1, &b) }.to yield_control.at_most(3).times }
end
So for your case it should be something like this:
expect{ foobar.some_method }.to yield_control
How to test a method with a parameter using RSpec?
my_param
should be defined inside the it
block or you should use let
to define my_param
Inside it block
describe Job do
let(:job) { Job.new }
describe 'run_job' do
context 'success' do
it 'should pass' do
my_param = [{"job1" => "run"}, {"job2" => "run again"}]
test_result = job.run_job(my_param)
expect(test_result[0]["job1"]).to eq("run")
end
end
end
end
Using let
describe Job do
let(:job) { Job.new }
describe 'run_job' do
context 'success' do
let(:my_param) { [{"job1" => "run"}, {"job2" => "run again"}] }
it 'should pass' do
test_result = job.run_job(my_param)
expect(test_result[0]["job1"]).to eq("run")
end
end
end
end
Using before block
describe Job do
let(:job) { Job.new }
describe 'run_job' do
context 'success' do
before(:all) do
@my_param = [{"job1" => "run"}, {"job2" => "run again"}]
end
it 'should pass' do
test_result = job.run_job(@my_param)
expect(test_result[0]["job1"]).to eq("run")
end
end
end
end
Related Topics
How to HTML_Escape Text Data in a Sinatra App
Ruby Range: Operators in Case Statement
Can Anyone Explain This Array Declaration to Me
Ternary Expression with "Defined" Returns "Expression" Instead of Value
Openssl Causing Very Slow Rails Boot Time on Windows
Error Requiring Pg Under Rvm with Postgres.App
Why Aren't "Gem" and "Bundle" Using the Same Libxml2
Rails 3: Belongs_To, Has_One and Migrations
New Way of Creating Hashes in Ruby 2.2.0
Bundler: Not Executable: Script/Delayed_Job
While Executing Gem ... (Argumenterror) Unknown Encoding Name - Cp720
How to Make Empty Tags Self-Closing with Nokogiri
How to Http Post Stream Data from Memory in Ruby
Convert Spreadsheet Column Index into Character Sequence