Rspec Rake Task 如何parse/simulate 用户输入?

Rspec Rake Task how to parse/simulate user input?

在我的抽佣任务中我有:

namespace :example do
  desc "this does something"
  task :something, [:arg1] => :environment do |t, args|

   (some_irrelevant_code)

    print 'YES/ NO : '
    choice = STDIN.gets.chomp.upcase

    case choice
    when 'YES'
     do_something
     break
    when 'NO'
     break
    end

  end
end

在我的规范中我有:

require "spec_helper"
require "rake"

feature "Example" do
  before do
    load File.expand_path("../../../lib/tasks/example.rake", __FILE__)
    Rake::Task.define_task(:environment)
  end

scenario "something" do
 Rake.application.invoke_task("example:something[rake_args_here]")
end

一切正常,尽管我无法找到避免在 运行测试时在控制台中键入用户输入的方法。

基本上我希望测试 运行 并假设用户将键入 "YES".

如果您对此有解决方案或指出正确的方向,请告诉我。

提前致谢。

你应该存根 STDIN 像这样的对象 STDIN.stub(gets: 'test')

allow(STDIN).to receive(:gets).and_return('test')

如果两者都不起作用,请尝试:

allow(Kernel).to receive(:gets).and_return('test')

如果您使用 STDIN,您就会卡住,这是一个常量。值得注意的是,由于此限制,不建议使用 STDIN

如果使用$stdin,全局变量等效和现代替换,可以重新赋值:

require 'stringio'
$stdin = StringIO.new("fake input")

$stdin.gets.chomp.upcase
# => "FAKE INPUT"

这意味着您可以出于测试目的返工 $stdin。不过,你会想把它放回去,这意味着你需要这样的包装器:

def with_stdin(input)
  prev = $stdin
  $stdin = StringIO.new(input)

  yield

ensure
  $stdin = prev
end

所以在实践中:

with_stdin("fake input") do
  puts $stdin.gets.chomp.upcase
end