如何使用gets.chomp测试函数?

use*_*596 7 ruby testing shell unit-testing

我有一个使用gets.chomp的简单函数,如下所示:

def welcome_user
   puts "Welcome! What would you like to do?"
   action = gets.chomp
end 
Run Code Online (Sandbox Code Playgroud)

我想用这样ruby的内置TestCase套件测试它:

class ViewTest < Test::Unit::TestCase
   def test_welcome
      welcome_user      
   end 
end 
Run Code Online (Sandbox Code Playgroud)

问题是,当我运行该测试时,gets.chomp停止测试,因为它需要用户输入某些内容.有没有办法可以使用模拟用户输入ruby

Ste*_*fan 13

您可以创建一个管道并将其"读取结束"分配给$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
Run Code Online (Sandbox Code Playgroud)

  • 感谢那个`IO.pipe`,你在那里教了我一些东西。 (2认同)

Bor*_*cky 7

您首先分离了该方法的两个问题:

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
Run Code Online (Sandbox Code Playgroud)

然后你分别测试第二个.

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
Run Code Online (Sandbox Code Playgroud)

至于第一个,你可以

  1. 手工测试并依靠它不会破坏(推荐的方法,TDD不是宗教).
  2. 获取有问题的shell的颠覆版本并使其模仿用户,并比较是否get_action确实获得了用户输入的内容.

虽然这是对你的问题的实际答案,但我不知道如何做2.我只知道如何模仿浏览器后面的用户(watir-webdriver)而不是shell会话.