我有使用gets.chomp这样一个简单的函数:
def welcome_user
puts "Welcome! What would you like to do?"
action = gets.chomp
end
我想继续使用,以测试它ruby
的内置TestCase
套件是这样的:
class ViewTest < Test::Unit::TestCase
def test_welcome
welcome_user
end
end
问题是,当我运行测试时, gets.chomp
停止测试,因为它需要用户的东西进入。 有没有一种方法,我可以只使用模拟用户输入ruby
?
你先分开2所担忧的方法:
def get_action
gets.chomp
end
def welcome_user
puts "Welcome to Jamaica and have a nice day!"
action = get_action
return "Required action was #{action}."
end
然后你分别测试了第二个。
require 'minitest/spec'
require 'minitest/autorun'
describe "Welcoming users" do
before do
def get_action; "test string" end
end
it "should work" do
welcome_user.must_equal "Required action was test string."
end
end
至于第一个,你可以
- 手工测试,并依靠它不会破裂(推荐的方法,TDD是不是宗教)。
- 获取有关壳的颠覆版本,并使其模仿用户,并且比较是否
get_action
确实得到什么类型的用户。
虽然这是一个实际的解决您的问题,我不知道该怎么办2,我只知道如何模仿浏览器(后面的用户watir-webdriver
),而不是shell会话后面。
您可以创建一个管道 ,并分配其“读结束” $stdin
。 写入管道的“写结束”,然后模拟用户输入。
这里有一个小的辅助方法的例子with_stdin
用于设置管:
require 'test/unit'
class View
def read_user_input
gets.chomp
end
end
class ViewTest < Test::Unit::TestCase
def test_read_user_input
with_stdin do |user|
user.puts "user input"
assert_equal(View.new.read_user_input, "user input")
end
end
def with_stdin
stdin = $stdin # remember $stdin
$stdin, write = IO.pipe # create pipe assigning its "read end" to $stdin
yield write # pass pipe's "write end" to block
ensure
write.close # close pipe
$stdin = stdin # restore $stdin
end
end
你可以注入IO依赖。 gets
从读取STDIN
,这是阶级IO
。 如果你注入其他IO
对象到类,你可以使用StringIO
在你的测试。 事情是这样的:
class Whatever
attr_reader :action
def initialize(input_stream, output_stream)
@input_stream = input_stream
@output_stream = output_stream
end
def welcome_user
@output_stream.puts "Welcome! What would you like to do?"
@action = get_input
end
private
def get_input
@input_stream.gets.chomp
end
end
测试:
require 'test/unit'
require 'stringio'
require 'whatever'
class WhateverTest < Test::Unit::TestCase
def test_welcome_user
input = StringIO.new("something\n")
output = StringIO.new
whatever = Whatever.new(input, output)
whatever.welcome_user
assert_equal "Welcome! What would you like to do?\n", output.string
assert_equal "something", whatever.action
end
end
这允许你的类与任何IO流(TTY,文件,网络等)进行交互。
要使用它在生产代码的控制台上,通过在STDIN
和STDOUT
:
require 'whatever'
whatever = Whatever.new STDIN, STDOUT
whatever.welcome_user
puts "Your action was #{whatever.action}"