Reputation: 41
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
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
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