【问题标题】:Ruby, Rspec, and yield stubbingRuby、Rspec 和产量存根
【发布时间】:2019-02-16 21:21:08
【问题描述】:

假设我在 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

我的问题是:如何对我的 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

但它总是打印相同的名称 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次不同的名字。可能吗 ? 提前致谢!

【问题讨论】:

    标签: ruby-on-rails ruby unit-testing rspec yield


    【解决方案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
    

    【讨论】:

    • 太棒了!非常感谢 !它完美无缺!并感谢您的提示。
    【解决方案2】:

    另一种选择是像这样使用receive的块语法

    allow(friends).to receive(:search_for_names) do |_,&block| 
      block.call(Faker::Name.name, Faker::Name.last_name)
    end
    

    我们捕获块 (&block),然后使用 Faker 参数显式调用它,而不是隐式地 yielding 到块。

    这避免了内部循环 40 次来生成 allowances 的需要,因为每次调用 search_for_names 都会再次执行此块。

    Repl Example

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-29
      • 1970-01-01
      • 2012-12-29
      • 1970-01-01
      • 2019-04-25
      相关资源
      最近更新 更多