Let's say I have a class like this in Ruby:
class Test
def execute
count = 0
40.times do
search_for_names(count) do |name, last_name|
yield name, last_name
end
count += 1
end
end
def search_for_names(count)
friend = get_friend_name(count)
yield friend.name, friend.last_name
end
end
My question is: how do I do to stub my search_for_names method to get 40 different names in my Rspec test? (I installed Faker). I tried:
let(:friends) do
described_class.new
end
allow(friends).to receive(:search_for_names).and_yield(
Faker::Name.name,
Faker::Name.last_name
)
it 'finds multiple friends' do
friends.execute do |name, last_name|
puts name
expect(name).not_to be_empty
expect(last_name).not_to be_empty
end
end
But it prints always the same name x40.
And... :
allow(friends).to receive(:search_for_names).and_yield(
Faker::Name.name,
Faker::Name.last_name
).and_yield(
Faker::Name.name,
Faker::Name.last_name
)
But it prints two different names x40 (80 names). But I would like to have only 40 times a different name. Is it possible ? Thanks in advance !
The issue is .and_yield(Faker::Name.name, Faker::Name.last_name)
is being executed once. Your function is already prepared to receive a param, use it:
40.times do |i|
allow(friends).to receive(:search_for_names).with(i).and_yield(
"#{Faker::Name.name}_#{i}",
"#{Faker::Name.last_name}_#{i}"
)
end
Sidenote: instead of introducing a local variable count
, just use what Integer#times
passes to the block:
def execute
40.times do |count|
search_for_names(count) do |name, last_name|
yield name, last_name
end
end
end