Как избежать использования allow_any_instance_of, если вы издеваетесь над методом, который находится внутри тестируемого экземпляра - PullRequest
0 голосов
/ 17 января 2019

Я хочу протестировать initialize нового объекта, и в рамках этой инициализации есть вызов метода, который мне нужно смоделировать (этот метод просит пользователя ввести имя ... типичный случай)

  class Setup
    attr_reader :player
    def initialize
      @player = new_player(cli_input('the name'))
    end

    private

    def cli_input('the name') # <<-- need to mock
      $stdin.gets.chomp.strip   
    end

    def new_player(name)
      Player.new(name)
    end
  end

setup_spec.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

Это работает, но с использованием allow_any_instance_of

Как я могу проверить это без allow_any_instance_of? , как я прочитал, его не следует использовать

Большое спасибо

1 Ответ

0 голосов
/ 17 января 2019

Если вы хотите использовать вызов частного метода внутри функции инициализации, я сомневаюсь, что нет метода, кроме allow_any_instance_of. А вставка строкового литерала the name в определение метода является неправильным синтаксисом.

Однако вы можете реорганизовать свой код, чтобы использовать test double для упрощения тестирования.

Код ниже демонстрирует мою идею:

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

setup_spec.rb

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
...