【问题标题】:Rspec:: allow every instance to receive a messageRspec:: 允许每个实例接收消息
【发布时间】:2015-03-26 05:58:50
【问题描述】:

我想为类的每个实例模拟一个方法。 如果我allow_any_instance_of 那么如果instance_count = 1 效果很好

但是,如果我有许多同一个类的实例,则第二个实例不会被模拟捕获。

我正在尝试从不同的站点获取一堆令牌。但在测试期间,我真的不需要“真正的”令牌。所以我打算模拟 get_token 以返回'1111'。

class Foo
  def children
     [Bar.new, Bar.new] #....
  end
  def get_tokens
     children.map(&:get_token) || []
  end
end

那么现在我如何不模拟 get_tokens?

【问题讨论】:

  • 你能通过在children方法中使用x.times.map { double('Bar', get_token: '1111') }来简化任务吗?否则你将不得不使用元编程来创建allow_any_instance_of 模拟

标签: ruby-on-rails ruby testing rspec mocking


【解决方案1】:

这样的解决方案怎么样:

require "spec_helper"
require "ostruct"

class Bar
  def get_token
    ("a".."f").to_a.shuffle.join # simulating randomness
  end
end

class Foo
  def children
    [Bar.new, Bar.new, Bar.new]
  end

  def get_tokens
    children.map(&:get_token) || []
  end
end

RSpec.describe Foo do
  before do
    allow(Bar).to receive(:new).and_return(OpenStruct.new(get_token: "123"))
  end

  it "produces proper list of tokens" do
    expect(Foo.new.get_tokens).to eq ["123", "123", "123"]
  end
end

我们在Bar 上存根new 方法以返回一些get_token 一起嘎嘎声(所以它的行为类似于Bar),并且它返回一个固定的字符串。这是你可以转发的东西。

希望有帮助!

【讨论】:

  • 谢谢伙计。我最终嘲笑了孩子,但感觉很脏,感觉就像我在测试模拟,而不是实际功能。仍然很有帮助的答案。跨度>
猜你喜欢
  • 1970-01-01
  • 2018-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-06
相关资源
最近更新 更多