Rspec Rake Task如何解析/模拟用户输入?

问题描述 投票:0回答:2

在我的佣金任务中,我有:

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”。

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

提前致谢。

ruby-on-rails ruby ruby-on-rails-4 rspec rspec-rails
2个回答
2
投票

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

要么

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

如果它们都不起作用,请尝试:

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


3
投票

如果你使用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
© www.soinside.com 2019 - 2024. All rights reserved.