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