Joao Quaresma
Joao Quaresma

Reputation: 41

Rspec Rake Task how to parse/simulate user input?

In my rake task I have:

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

In my spec I have:

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

All is working fine, although I am having troubles finding a way to avoid having to type the user input in the console when running the test.

Basically I want the test to run and assume that the user is going to type "YES".

Please let me know if you have a solution for this or point me in the right direction.

Thanks in advance.

Upvotes: 0

Views: 441

Answers (2)

zeitnot
zeitnot

Reputation: 1314

You should stub STDIN object like this STDIN.stub(gets: 'test')

or

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

If both of them do not work then try:

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

Upvotes: 2

tadman
tadman

Reputation: 211560

If you use STDIN, you're stuck, that's a constant. It's worth noting that using STDIN is not recommended because of this limitation.

If you use $stdin, the global variable equivalent and modern replacement, you can reassign it:

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

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

That means you can, for testing purposes, rework $stdin. You'll want to put it back, though, which means you need a wrapper like this:

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

  yield

ensure
  $stdin = prev
end

So in practice:

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

Upvotes: 3

Related Questions