Skip to content

Instantly share code, notes, and snippets.

@JoshCheek
Created October 17, 2011 15:52
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save JoshCheek/1292923 to your computer and use it in GitHub Desktop.
Example of testing method that interacts with IO
require 'rake/testtask'
task :default => :test
Rake::TestTask.new do |t|
t.test_files = FileList['test/**/*_test.rb']
end
require 'user_prompter'
require 'test/unit'
require 'stringio'
class UserPrompterReaderTest < Test::Unit::TestCase
def read(input)
input_stream = StringIO.new input
UserPrompter::Reader.read_int(input_stream)
end
def test_with_an_int
assert_equal 12, read('12')
end
def test_with_leading_char
refute read('a12')
end
def test_with_trailing_char
refute read('12a')
end
def test_with_char_in_middle
refute read('1a2')
end
end
class UserPrompter
def self.integer(reader=Reader, writer=Writer)
writer.ask_for_int
int = reader.read_int
return int if int
writer.notify_not_an_int
self.integer reader, writer
end
class Writer
def self.ask_for_int(output_stream=$stdout)
output_stream.print 'Enter an integer: '
end
def self.notify_not_an_int(output_stream=$stdout)
output_stream.puts 'That is not an integer'
end
end
class Reader
def self.read_int(input_stream=$stdin)
input = input_stream.gets
input[/^\d+$/] && input.to_i
end
end
end
require 'user_prompter'
require 'test/unit'
# tests
class UserPrompterTest < Test::Unit::TestCase
def setup
@reader = MockReader.new
@writer = MockWriter.new
end
def test_integer_happy_path
@reader.int_responses = [12]
assert_equal 12, UserPrompter.integer(@reader, @writer)
assert_equal 1, @reader.times_read
assert_equal 1, @writer.times_asked_for_int
assert_equal 0, @writer.times_notified_not_an_int
end
def test_integer_two_invalid_inputs
@reader.int_responses = [nil, false, 1212]
assert_equal 1212, UserPrompter.integer(@reader, @writer)
assert_equal 3, @reader.times_read
assert_equal 3, @writer.times_asked_for_int
assert_equal 2, @writer.times_notified_not_an_int
end
end
# mocks
class UserPrompterTest
class MockWriter
attr_accessor :times_asked_for_int, :times_notified_not_an_int
def initialize
self.times_asked_for_int = self.times_notified_not_an_int = 0
end
def ask_for_int
self.times_asked_for_int += 1
end
def notify_not_an_int
self.times_notified_not_an_int += 1
end
end
class MockReader
attr_accessor :times_read, :int_responses
def initialize
self.times_read = 0
end
def read_int
self.times_read += 1
int_responses.shift
end
end
end
require 'user_prompter'
require 'test/unit'
require 'stringio'
class UserPrompterWriterTest < Test::Unit::TestCase
def setup
@stream = StringIO.new
@writer = UserPrompter::Writer
end
def test_ask_for_int
@writer.ask_for_int @stream
@stream.rewind
refute @stream.read.empty?
end
def test_notify_not_an_int
@writer.notify_not_an_int @stream
@stream.rewind
refute @stream.read.empty?
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment