[英]Ruby, Rspec, and yield stubbing
Let's say I have a class like this in Ruby: 假设我在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? 我的问题是:如何在Rspec测试中存根我的search_for_names方法以获得40个不同的名称? (I installed Faker).
(我安装了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. 但是它始终打印相同的名称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). 但是它将打印两个不同的名称x40(80个名称)。 But I would like to have only 40 times a different name.
但我只想使用40个不同的名字。 Is it possible ?
可能吗 ? Thanks in advance !
提前致谢 !
The issue is .and_yield(Faker::Name.name, Faker::Name.last_name)
is being executed once . 问题是
.and_yield(Faker::Name.name, Faker::Name.last_name)
被执行一次 。 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: 旁注:不用引入局部变量
count
,而只需使用Integer#times
传递给块的内容即可:
def execute
40.times do |count|
search_for_names(count) do |name, last_name|
yield name, last_name
end
end
end
Another option is to use the block syntax of receive
like so 另一个选择是像这样使用
receive
的块语法
allow(friends).to receive(:search_for_names) do |_,&block|
block.call(Faker::Name.name, Faker::Name.last_name)
end
rather than implicitly yielding
to the block instead we capture the block ( &block
) and then explicitly call it with the Faker
arguments. 而不是隐式
yielding
该块,而是捕获该块( &block
),然后使用Faker
参数显式调用它。
This avoids the need for the internal loop 40 times to make allow
ances as every time search_for_names
is called this block will be executed again. 由于每次调用
search_for_names
,此循环将再次执行,因此无需40次内部循环即可进行allow
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.