【问题标题】:Rspec Rake Task how to parse/simulate user input?Rspec Rake Task如何解析/模拟用户输入?
【发布时间】:2019-07-16 20:38:05
【问题描述】:

在我的 rake 任务中,我有:

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


    【解决方案1】:

    如果你使用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
    

    【讨论】:

    • 我没有尝试过这个,因为上一个回复中的解决方案有效,但这似乎也是一个很好的解决方案。非常感谢回复
    • 使用模拟,就像在其他回复中一样,您需要调用特定的方法才能使其正常工作。这是一个更通用的解决方案,但无论对你有用。
    【解决方案2】:

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

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

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

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

    【讨论】:

    • allow(STDIN).to receive(:gets).and_return('YES') 这非常有效。感谢您的帮助
    猜你喜欢
    • 2016-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-23
    • 1970-01-01
    相关资源
    最近更新 更多