如何使用 RSpec 模拟多个 `gets`(用户输入)

How to simulate multiple `gets` (user input) with RSpec

这个项目是一个简单的 Ruby 项目,Github Repo,我正在尝试使用 TDD 重新构建它,我正在使用 Ruby (ruby 2.7.3) 和 rspec (RSpec 3.10).

我的问题是,无论我如何尝试模拟用户输入(请参阅下面我的“测试代码 的注释行以查看我尝试过的内容。)

我错过了什么吗?我觉得我不太了解这一点,我已经尝试了在 Google.

上可以找到的大部分建议

我正在测试 AddressChecker class,具体功能如下:


  def handle_manual_input 
      puts "Add at least 2 Addresses, hit enter after each address, type 'quit' when done"
      while true do
        address = gets.chomp
        break if address == "quit"
        check_ethereum_address_validity(address) ? @origin_addresses << address : (puts "Error: Invalid Ethereum Address")
      end
  end

  def input_origin_addresses_manually?(y_n)  

        if y_n == "y"
      handle_manual_input
    elsif y_n == "n"
      @origin_addresses = ["0x72140C1886f8F2Dd932DCe06795901F8FB6378a7","0x0613Cd2076bd432C7A60a1b926b11B17BaAaFE11"]
    else 
      print "Please only enter 'y' or 'n' into 'input_origin_addresses_manually'"
    end
      
  end

我正在尝试测试 input_origin_addresses_manually?("y") 的输出是否会填充 @origin_addresses 超过 1 个地址。

当我 运行 rspec 时,系统会提示我输入用户信息(因为我的 address = gets.chomphandle_manual_input.

rspec 的终端输出:

➜  cryptoAddressWeb git:(main) ✗ rspec
...Add at least 2 Addresses, hit enter after each address, type 'quit' when done

我想要的输入会像这样循环:

...Add at least 2 Addresses, hit enter after each address, type 'quit' when done
0xa95aea385130718be87b380b419eeac8da40de55
0xa95aea385130718be87b380b419eeac8da40de55
quit
....

测试代码

    it 'If user wants to add their own addresses, check that they add more than 1 address' do
      subject.input_origin_addresses_manually?("y")

      # let(:user_input) { ["rock\n", "rock\n"] }
      # allow_any_instance_of(Object).to receive(:gets).and_return('0xa95aea385130718be87b380b419eeac8da40de55', '0xa95aea385130718be87b380b419eeac8da40de55', 'quit')
      # expect(subject).to receive(:puts).with("Add at least 2 Addresses, hit enter after each address, type 'quit' when done")
      # allow(subject).to receive(:gets).and_return('0xa95aea385130718be87b380b419eeac8da40de55', '0xa95aea385130718be87b380b419eeac8da40de55', 'quit')
      # subject.stub(gets: 'user input')
      # expect(STDOUT).to receive(:puts).with("Add at least 2 Addresses, hit enter after each address, type 'quit' when done")
      # allow(STDIN).to receive(:gets).and_return('0xa95aea385130718be87b380b419eeac8da40de55', '0xa95aea385130718be87b380b419eeac8da40de55', 'quit')
      # expect($stdout).to receive(:puts).with("Add at least 2 Addresses, hit enter after each address, type 'quit' when done")
      # allow($stdin).to receive(:gets).and_return('0xa95aea385130718be87b380b419eeac8da40de55', '0xa95aea385130718be87b380b419eeac8da40de55', 'quit')

      expect(subject.origin_addresses.length).to be > 1
    end

非常感谢帮助!

谢谢, 埃德

[How to] Simulate Multiple Gets (User Input) on rspec

class Inquisitor
  def gets_twice
    [gets, gets]
  end
end

RSpec.describe Inquisitor do
  describe '#gets_twice' do
    it 'calls gets twice' do
      inq = Inquisitor.new
      allow(inq).to receive(:gets).and_return('Apricot', 'Banana')
      expect(inq.gets_twice).to eq(%w[Apricot Banana])
    end
  end
end