如何使用gets.chomp测试函数?
我有一个使用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
模拟用户输入?
您首先将该方法的两个问题分开:
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不是宗教)。
- 获取有问题的shell的颠覆版本并使其模仿用户,并比较
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依赖项。 从STDIN
gets
读取,这是类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}"