'Can we actually do rspec testing on ruby if my methods don't have parameters?

I have a method but doesn't have a parameter, for example

def goodbye
    puts ""
    puts "Thank you, #{name} for using our service."
    puts "Good luck with your future trip!"
    puts ""
end

How can I do rpsec testing with this method that doesn't have a parameter ?

Alex advised me using the solution:

expect(goodbye).to output(/#{name}/).to_stdout

so my rspec code is like this:

describe "goodbye" do
    
    it "should return goodbye with a name as input" do
        expect(goodbye).to output(/#{name}/).to_stdout
    end
end

But I got this error msg:

F

Failures:

  1) goodbye should return goodbye with a name as input
     Failure/Error: expect(goodbye).to output(/#{name}/).to_stdout
       `name` is not available from within an example (e.g. an `it` block) or from constructs that run in the scope of an example (e.g. `before`, `let`, etc). It is only available on an example group (e.g. a `describe` or `context` block).
     # ./test2.rb:41:in `goodbye'
     # ./spec/tcs_spec.rb:24:in `block (2 levels) in <top (required)>'

Finished in 0.00211 seconds (files took 0.07718 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./spec/tcs_spec.rb:23 # goodbye should return goodbye with a name as input


Solution 1:[1]

name is an RSpec method. It can be used outside an it to print the name of a spec, like this:

RSpec.describe Greeter do
  describe "#goodbye" do
    puts "Spec name: #{name}"
  end
end

Which will output this: Spec name: RSpec::ExampleGroups::Greeter::Goodbye

When your expectation calls /#{name}/, you are interpolating a variable called name into a regular expression that will match the value of the variable in the output of the method to_stdout.

And, since you didn't declare a variable named name, RSpec tried to call its own name method which cannot be executed inside the context of an it statement (as the error states).

So, in order to get your test working, you need to declare a variable named name. You can do that inside the it statement (name = "skyline"), or you can do that with a let statement. Here's what the latter looks like (along with a subject to create the object and call the goodbye method...

RSpec.describe Greeter do
  describe "#goodbye" do
    subject(:goodbye) { Greeter.new.goodbye }

    let(:name) { "skylinerr" }

    it "should return goodbye with a name as input" do
      expect { goodbye }.to output(/#{name}/).to_stdout
    end
  end
end

Note that @Alex was close, but not quite right. We need to call goodbye from a block (inside curly braces), not as a value (inside parentheses), since we're checking the output of the method to_stdout rather than the return value of the goodbye method which is nil.

For completeness, here's the class I wrote to get this test to pass...

class Greeter
  def goodbye
    puts ""
    puts "Thank you, #{name} for using our service."
    puts "Good luck with your future trip!"
    puts ""
  end

  def name
    "skylinerr"
  end
end

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 aridlehoover