Skip to content

Instantly share code, notes, and snippets.

@jasonm
Created September 27, 2009 02:10
Show Gist options
  • Save jasonm/194554 to your computer and use it in GitHub Desktop.
Save jasonm/194554 to your computer and use it in GitHub Desktop.
Faking $stdin for testing in Ruby
require 'test/unit'
class InputFaker
def initialize(strings)
@strings = strings
end
def gets
next_string = @strings.shift
# Uncomment the following line if you'd like to see the faked $stdin#gets
# puts "(DEBUG) Faking #gets with: #{next_string}"
next_string
end
def self.with_fake_input(strings)
$stdin = new(strings)
yield
ensure
$stdin = STDIN
end
end
class Waiter
attr_accessor :orders
attr_reader :number_of_diners
def initialize(number_of_diners)
@number_of_diners = number_of_diners
end
def take_orders!
self.orders = {}
number_of_diners.times do |n|
puts "Hello, diner #{n}. What is your name?"
name = gets
puts "Please to meet you. #{name}, what would you like for dinner?"
order = gets
self.orders[name] = order
end
end
end
class WaiterTest < Test::Unit::TestCase
def test_ordering
InputFaker.with_fake_input(["Harry", "The tarte tomate",
"Sally", "The pulled pork sandwich"]) do
waiter = Waiter.new(2)
waiter.take_orders!
assert waiter.orders.keys.include?("Harry")
assert waiter.orders.keys.include?("Sally")
assert_equal "The tarte tomate", waiter.orders["Harry"]
assert_equal "The pulled pork sandwich", waiter.orders["Sally"]
end
end
end
@daniely
Copy link

daniely commented May 27, 2011

I think this code is awesome and I'm using it in my specs but I can't get it to work with just "gets". I have to specify "$stdin.gets". Any idea why? Oh yeah, I'm on ruby 1.9

@jasonm
Copy link
Author

jasonm commented May 29, 2011 via email

@daniely
Copy link

daniely commented Jun 1, 2011

Ah, I think it's because I'm using it in rspec. This is what I get

#<Method: RSpec::Core::ExampleGroup::Nested_1(Kernel)#gets>

If I don't specify $stdin.gets then gets will start grabbing lines of the spec source code. So instead of the string array I passed to with_fake_input it starts parsing my source code. I don't know how it's all working well enough to fix it but the workaround for me is to just keep using $stdin in my specs.

@nithincb-oss
Copy link

Is there a license to the code above?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment