Reputation: 13262
My class has this #run method that so far is just this, to test the testing:
def run
puts "Enter 'class' to create a new class."
input = $stdin.gets.chomp
binding.pry
And in the tests so far I've got
allow($stdin).to receive(:gets).and_return 'class'
cli.run
Doing it this way I am able to see, in the pry session, that input
has been set to 'class'
, as intended.
Is there a way to do with without adding $stdin
to my call to gets
in my method itself? i.e., input = gets.chomp
I've tried allow(cli.run).to receive(:gets).and_return 'class'
But then in the pry session, input
is equal to the first line of the spec file!
Upvotes: 0
Views: 1266
Reputation: 29328
You can avoid this as such:
def run
puts "Enter 'class' to create a new class."
input = gets.chomp
end
describe 'gets' do
it 'belongs to Kernel' do
allow_any_instance_of(Kernel).to receive(:gets).and_return('class')
expect(run).to eq('class')
end
end
The method gets
actually belongs to the Kernel
module. (method(:gets).owner == Kernel
). Since Kernel
is included in Object
and almost all ruby objects inherit from Object
this will work.
Now if run
is an instance method scoped in a Class
I would recommend scoping the stubbing a bit more such that:
class Test
def run
puts "Enter 'class' to create a new class."
input = gets.chomp
end
end
describe 'gets' do
it 'can be stubbed lower than that' do
allow_any_instance_of(Test).to receive(:gets).and_return('class')
expect(Test.new.run).to eq('class')
end
# or even
it 'or even lower than that' do
cli = Test.new
allow(cli).to receive(:gets).and_return('class')
expect(cli.run).to eq('class')
end
end
Upvotes: 2