Sey*_*bol 3 ruby unit-testing rspec yield ruby-on-rails
假设我在 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
Run Code Online (Sandbox Code Playgroud)
我的问题是:如何对 search_for_names 方法进行存根处理,以在 Rspec 测试中获取 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
Run Code Online (Sandbox Code Playgroud)
但它总是打印相同的名称 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
)
Run Code Online (Sandbox Code Playgroud)
但它打印两个不同的名称 x40(80 个名称)。但我只希望有 40 次不同的名字。是否可以 ?提前致谢 !
问题是.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
Run Code Online (Sandbox Code Playgroud)
旁注:不用引入局部变量count,只需使用Integer#times传递给块的内容:
def execute
40.times do |count|
search_for_names(count) do |name, last_name|
yield name, last_name
end
end
end
Run Code Online (Sandbox Code Playgroud)
另一种选择是使用receive像这样的块语法
allow(friends).to receive(:search_for_names) do |_,&block|
block.call(Faker::Name.name, Faker::Name.last_name)
end
Run Code Online (Sandbox Code Playgroud)
我们不是隐式地yielding捕获块(&block),而是使用Faker参数显式调用它。
这避免了内部循环 40 次的需要,allow因为每次search_for_names调用该块都会再次执行。
| 归档时间: |
|
| 查看次数: |
8865 次 |
| 最近记录: |