rspec commandline variable input
You can stub Kernel#gets
, except that it is mixed into the object, so stub it there:
class Mirror
def echo
print "enter something: "
response = gets.chomp
puts "#{response}"
end
end
require 'rspec'
describe Mirror do
it "should echo" do
@mirror = Mirror.new
@mirror.stub!(:gets) { "phrase\n" }
@mirror.should_receive(:puts).with("phrase")
@mirror.echo
end
end
Rspec command line argument not supported?
According to this post on the ruby forum, you cannot pass argument to rspec
, but you can pass variable from the command line via the environment variables
- command line ( on Linux / bash )
LANG=1 BROWSER=2 rspec testFile.rb
- command line ( on Windows )
set LANG=1
set BROWSER=2
rspec testFile.rb
- in your
testFile.rb
argOne = ENV["LANG"].to_i
argTwo = ENV["BROWSER"].to_i
Telling the rspec which input to use in a interactive ruby script?
This isn't meant to answer your asked question; It's to help you write better code.
I'd probably write it something like this to clean it:
def self.check_target
entry = ask 'What kind of entry do you have? (Interpret or Group)'
subdir = case entry
when 'Interpret'
[
ask('Whats the first name of your interpret?'),
ask('Whats the surname of your interpret?')
].join('_')
when 'Group'
ask 'Whats the name of the group?'
else
puts 'Just the entries "Interpret" or "Group" are allowed'
puts 'Breakpoint'
abort('Aborted')
end
"#{ subdir }/Youtube-Music"
end
It's questionable whether $folder
in your code should be a global. Usually you want to avoid that completely and either return a value directly from the method without assigning it, like above or use an assignment to a class variable:
@@folder = "#{ subdir }/Youtube-Music"
Returning a value, instead of assigning it, makes more sense to me, because you're trying to get a path to use.
Also, assigning to instance variables inside a class method makes no sense. Just use local variables.
Add both things together and it looks like you're not comfortable with how variable scope works. You might want to work on that.
Rspec 3 stubbing user input
In order to silence test results from appearing in the command line when you run specs, you can stub out $stdout
's output stream:
before do
allow($stdout).to receive(:write)
end
In order to send a return character with your stubbed input, you'll need to provide it with a newline character:
allow(greeting).to receive(:gets).and_return("Brian\n")
How to write Rspec test for running file from command line?
Don't Use the RSpec Output Matcher
RSpec has a built-in output matcher than can test both where output goes, as well as its contents. However, it's testing where your Ruby output goes, not whether some external application is using standard input or standard error. You're going to have to make some different assumptions about your code.
You can avoid driving yourself nuts by comparing strings rather than testing the underlying shell or your output streams. For example, consider:
RSpec.describe "parse utility output" do
it "prints the right string on standard output" do
expect(`echo hello world`).to start_with("hello world")
end
it "shows nothing on standard output when it prints to stderr" do
expect(`echo foo >&2 > /dev/null`).to be_empty
end
end
Just replace the echo statements with the correct invocation of parse
for your system, perhaps by setting PATH directly in your shell, using a utility like direnv, or by modifying ENV["PATH"]
in your spec or spec_helper.
As a rule of thumb, RSpec isn't really meant for testing command-line applications. If you want to do that, consider using the Aruba framework to exercise your command-line applications. It's best to use RSpec to test the results of methods or the output of commands, rather than trying to test basic functionality. Of course, your mileage may vary.
Rspec Selenium passing variable using through command and use that variable in test case
I solved this by adding the all of the test cases in rake task and I am calling it via.
email="abcAgmail.com,password" rake task:task
and its working fine for me.
How to test stdin for a CLI using rspec
I ended up finding a solution that I think fairly closely mirrors the code for executing instructions from a file. I overcame the main hurdle by finally realizing that I could write cli.stub(:gets).and_return
and pass it in the array of commands I wanted to execute (as parameters thanks to the splat *
operator), and then pass it the "EXIT"
command to finish. So simple, yet so elusive. Many thanks go to this StackOverflow question and answer for pushing me over the line.
Here is the code:
describe "executing instructions from the command line" do
let(:output) { capture(:stdout) { cli.execute } }
context "with valid commands" do
valid_test_data.each do |data|
let(:expected_output) { data[:output] }
let(:commands) { StringIO.new(data[:input]).map { |a| a.strip } }
it "should process the commands and output the results" do
cli.stub(:gets).and_return(*commands, "EXIT")
output.should include(expected_output)
end
end
end
# ...
end
Write test for accepting input from command line
By using mocks:
STDIN.should_receive(:read).and_return("your string")
Also I like the approach which is described here. I think that the last one is more suitable for your case.
RSpec loop testing with console input and output
Refactor to Inject Your Test Inputs into the "Real" Method
This is a common problem for code that isn't written test-first. There are a couple of ways to solve it, but the simplest option without mocking, stubbing, or otherwise invalidating your "real" code is simply to refactor the method itself. For example:
def read test_input: nil
loop do
print "#{RADIUS_QUERY_MSG}\n> "
radius = (test_input || gets).strip
return radius.to_f if valid?(radius)
puts INVALID_MSG
end
end
Now you can simply inject whatever values you want into the optional test_input keyword argument from your RSpec tests to ensure that the input is stripped properly and exhibits whatever other behavior you're testing for.
This avoids all sorts of problems you might experience by trying to write around a difficult-to-test method. Either you provide test input directly to the method, in which case the method uses that, or you don't, in which case it calls #gets just as it normally would.
Remember, the goal isn't to test core methods like #gets. Instead, you should be testing the behavior of your method or object given a particular input or state. If you make your methods testable by allowing dependency injection in your code, or refactoring your class to allow modifying instance variables in your test setup and using those rather than method arguments passed to your methods, you ensure that you are testing your real class or method rather than hacking your way around it.
There are certainly other, more complex ways to do what I did above, but they don't seem warranted for this specific example. The KISS principle definitely applies!
Related Topics
How to Use Same Browser Window for Automated Test Using Selenium-Webdriver (Ruby)
Install Cocoapods Failed on MAC
Ignoring a Character Along with Word Boundary in Regex
How to Declare 8-Bit Unsigned Integer in Ruby
Sorting an Array in Ruby Without Using Sort Method
New to Ruby - While Loop Issues in Irb
How to Determine If a String Is Numeric
How to Preload Concerns in a Rails Initializer Using Rails 6/Zeitwerk
Paperclip Error: Model Missing Required Attr_Accessor for 'Avatar_File_Name'
How to Disable Wait Time for Watir
Regular Expression "Empty Range in Char Class Error"
Call Ruby Script from Powershell
Your Ruby Version Is 2.1.0, But Your Gemfile Specified 2.0.0
Ruby Variable Name with Double Underscores
Why Doesnt My Ruby Coding for Finding Prime Numbers Work