Created
September 27, 2009 02:10
-
-
Save jasonm/194554 to your computer and use it in GitHub Desktop.
Faking $stdin for testing in Ruby
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Thanks. Not sure why you'd have to explicitly do $stdin.gets. I just check
that this works with Kernel#gets in 1.8.7-ree-2010.02 and 1.9.2-p180.
Is #gets the Kernel#gets method for you? If that's something else, it's a
place to look. Otherwise, I'm not sure what the issue would be.
ruby-1.9.2-p180 :001 > method(:gets)
=> #<Method: Object(Kernel)#gets>
On Fri, May 27, 2011 at 11:24 AM, daniely < ***@***.***>wrote:
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?
##
Reply to this email directly or view it on GitHub:
https://gist.github.com/194554
##
Jason Morrison
[email protected]
http://jayunit.net
(585) 216-5657
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.
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
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