Rywi
Rywi

Reputation: 143

How to simulate user input multiple times for gets

I based my UI on a console and case/when. I want to write some rspecs for the code. This is my piece of code:

case choice
when '1' #Create account
  puts 'Enter username:'
  username = gets.chomp
  puts 'Enter Password'
  password = gets.chomp
  #createAccount() returns 1 or -1 after checking the database for duplicates
  operation = System.createAccount(username, password) 
  if operation == -1
    puts 'Error!'
  else
    puts 'Success!'
  end
when '2' #login case
  #code omitted
end

I have to get past the gets.chomp operation. I found various suggestions like using allow method to get past it:

STDIN.stub(:gets).and_return('name')
STDIN.stub(:gets).and_return('password')

but that didn't help; running the rspec test doesn't allow the code to get past username = gets.chomp.

Do you have any suggestions how I should write the spec (I want to test if operation value is 1) so that it passes name and afterwards password?

Upvotes: 0

Views: 750

Answers (1)

Greg
Greg

Reputation: 6628

Well, gets is a method defined in Kernel module, which is included (mixed in) your class, so you could mock it like this:

describe do 
  subject { described_class.new }
  before do 
    allow(subject).to receive(:gets).and_return('name', 'password')
    # https://relishapp.com/rspec/rspec-mocks/v/3-6/docs/configuring-responses/returning-a-value#specify-different-return-values-for-multiple-calls 
  end

  specify do
    expect(System).to receive(:createAccount).with('name', 'password')
    subject.method_that_does_the_job
  end
end

(I assumed your case choice... code is inside method_that_does_the_job)

Some regard mocking tested object as a code smell (though I couldn't find any links that describe that, I'm sure I've read it somewhere).

Upvotes: 1

Related Questions