假设我在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
我的问题是:如何在我的Rspec测试中存根我的search_for_names方法以获得40个不同的名称? (我安装了Faker)。 我尝试过:
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
但是它总是打印相同的名字x40。
然后...:
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
)
但是它将打印两个不同的名称x40(80个名称)。但我只想使用40个不同的名字。可能吗 ? 预先感谢!
答案 0 :(得分:1)
问题是.and_yield(Faker::Name.name, Faker::Name.last_name)
被执行一次 。您的函数已经已准备好准备接收参数,请使用它:
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
侧注:而不是引入局部变量count
,而只需使用Integer#times
传递给块的内容即可。
def execute
40.times do |count|
search_for_names(count) do |name, last_name|
yield name, last_name
end
end
end
答案 1 :(得分:0)
另一种选择是像这样使用receive
的块语法
allow(friends).to receive(:search_for_names) do |_,&block|
block.call(Faker::Name.name, Faker::Name.last_name)
end
我们不是捕获块yielding
,而是捕获块(&block
),然后使用Faker
参数显式调用它。
这避免了每次调用allow
时都需要执行40次内部循环来产生search_for_names
实例的情况。