Rspec 如何避免在模拟被测试实例内的方法时使用的allow_any_instance_

Rspec 如何避免在模拟被测试实例内的方法时使用的allow_any_instance_,rspec,mocking,ruby-on-rails-5,Rspec,Mocking,Ruby On Rails 5,我想测试一个新对象的initialize,在这个initialize中调用了一个我需要模拟的方法(这个方法要求用户输入一个名称…典型情况) 这是可行的,但是使用allow\u任何\u实例 如果没有允许的任何实例,我如何测试它?,因为我已经读到它不应该被使用 非常感谢如果您想在initialize函数中使用call私有方法,我怀疑除了允许的任何实例之外,没有其他方法。在方法定义中使用字符串literal名称,是错误的语法 但是,您可以重构代码,使用TestDouble来更轻松地进行测试 下面的代码

我想测试一个新对象的
initialize
,在这个initialize中调用了一个我需要模拟的方法(这个方法要求用户输入一个名称…典型情况)

这是可行的,但是使用
allow\u任何\u实例

如果没有
允许
的任何实例,我如何测试它?,因为我已经读到它不应该被使用


非常感谢

如果您想在initialize函数中使用call私有方法,我怀疑除了
允许
的任何实例之外,没有其他方法。在方法定义中使用字符串literal
名称
,是错误的语法

但是,您可以重构代码,使用TestDouble来更轻松地进行测试

下面的代码演示了我的想法:

setup.rb

class Player
  attr_reader :name
  def initialize(name)
    @name = name
  end
end

class Setup
  class Client
    def cli_input
      $stdin.gets.chomp.strip
    end
  end

  attr_reader :player

  def initialize(client)
    @client = client
    @player = new_player(cli_input)
  end

  private

  def cli_input
    @client.cli_input
  end

  def new_player(name)
    Player.new(name)
  end
end
安装规格rb

RSpec.describe Battleship::Setup do
  describe 'initialize' do

    it 'creates a player assigned to a instance variable' do
      allow_any_instance_of(Setup).to receive(:cli_input).with('the name').and_return('John')
      setup = Battleship::Setup.new
      expect(setup.player.name).to eq('John')
    end
  end
end
RSpec.describe Setup do
  describe 'initialize' do

    it 'creates a player assigned to a instance variable' do
      client = Setup::Client.new
      allow(client).to receive(:cli_input).and_return("John")
      setup = Setup.new(client)
      expect(setup.player.name).to eq('John')
    end
  end
end

您应该在这里使用依赖项注入,它将解决这个问题并使代码更具可扩展性。
RSpec.describe Setup do
  describe 'initialize' do

    it 'creates a player assigned to a instance variable' do
      client = Setup::Client.new
      allow(client).to receive(:cli_input).and_return("John")
      setup = Setup.new(client)
      expect(setup.player.name).to eq('John')
    end
  end
end