ruby - How to simulate multiple `gets` (user input) with RSpec
问题描述
This project is a simple Ruby project, Github Repo, which I am trying to re-build using TDD, and I'm using Ruby (ruby 2.7.3) and rspec (RSpec 3.10).
My issue is, no matter how I try to simulate user input (see the commented out lines of my 'Test Code below to see what I've tried.)
Am I missing something? I feel like I don't understand this well enough, I've tried most of the suggestions I can find on Google.
- Code file: /lib/address_checker.rb
- Test file: /spec/address_checker_spec.rb
I am testing the AddressChecker class, specifically the following functions:
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
I'm trying to test whether the output of input_origin_addresses_manually?("y")
will populate @origin_addresses
with more than 1 address.
When I run rspec
though, I am prompted for user input (because of my address = gets.chomp
within handle_manual_input
.
Terminal Output from rspec
:
➜ cryptoAddressWeb git:(main) ✗ rspec
...Add at least 2 Addresses, hit enter after each address, type 'quit' when done
and my desired input would loop like this:
...Add at least 2 Addresses, hit enter after each address, type 'quit' when done
0xa95aea385130718be87b380b419eeac8da40de55
0xa95aea385130718be87b380b419eeac8da40de55
quit
....
Test Code
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
Would really appreciate assistance!
Thank you, Ed
解决方案
[如何] 在 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
推荐阅读
- mysql - 我将如何纠正这个 SQL/MYSQL FULL 外连接问题?
- php - 如何将输入图像文件传递给 PHP 中的父类方法?
- java - 使用 jdk11 运行 java 代码,但使用 jdk8 中的 tools.jar
- c# - 我可以在 C# 数组中存储不同的类型吗?
- python - Python套接字服务器-TypeError:需要像对象一样的咬,而不是“str”
- oracle - NEO4J 与 Oracle 数据库的连接
- php - json_encode 不想提供数据(或其他错误)
- python - 在 Python 中将结果存储在 n*m 矩阵中
- windows-services - 更改 Windows 服务的“开始”路径
- react-native - 将远程图像转换为文件 base64 格式