CiCi
CiCi

Reputation: 31

How to test a method with a parameter using RSpec?

I have the following RSpec:

describe Job do
  let(:job) { Job.new }

  describe 'run_job' do
    context 'success' do
        my_param = [{"job1" => "run"}, {"job2" => "run again"}]

        it 'should pass' do
            test_result = job.run_job(my_param)
            expect(test_result[0]["job1"]).to eq("run")
        end
     end
  end
end

The method:

Class Job
  def run_job(my_param)
    # puts "#{my_param}"
    my_param.each do|f|
      # do something
    end
  end
end

when I run the test I receive the following error

 NoMethodError:
   undefined method `each' for nil:NilClass

I print out my_param in the console and see same object that was passed to the test, [{"job1" => "run"}, {"job2" => "run again"}]. I have no idea why my_param is nil when calling .each. What did I do wrong? Any insight is appreciated.

Upvotes: 0

Views: 4815

Answers (3)

Ritesh Ranjan
Ritesh Ranjan

Reputation: 1012

One way would be defining in the before block and forming it the instance variable as;

before { @my_param = [{"job1" => "run"}, {"job2" => "run again"}] }

or

but the best way would be to use let:

describe Job do
  let(:job) { Job.new }
  let(:my_param) { [{"job1" => "run"}, {"job2" => "run again"}] }
  describe 'run_job' do
    context 'success' do

      it 'should pass' do
        test_result = job.run_job(my_param)
        expect(test_result[0]["job1"]).to eq("run")
      end
    end
  end
end

Upvotes: 0

spickermann
spickermann

Reputation: 106792

Better Specs recommends using let to assign variables:

describe Job do
  let(:job) { Job.new }

  describe 'run_job' do
    context 'success' do
      let(:my_param) { [{"job1" => "run"}, {"job2" => "run again"}] }

      it 'should pass' do
        test_result = job.run_job(my_param)
        expect(test_result[0]["job1"]).to eq("run")
      end
    end
  end
end

Upvotes: 0

Sampat Badhe
Sampat Badhe

Reputation: 9075

my_param should be defined inside the it block or you should use let to define my_param

Inside it block

describe Job do
  let(:job) { Job.new }

  describe 'run_job' do
    context 'success' do        
        it 'should pass' do
            my_param = [{"job1" => "run"}, {"job2" => "run again"}]

            test_result = job.run_job(my_param)
            expect(test_result[0]["job1"]).to eq("run")
        end
     end
  end
end

Using let

describe Job do
  let(:job) { Job.new }

  describe 'run_job' do
    context 'success' do
        let(:my_param) { [{"job1" => "run"}, {"job2" => "run again"}] }


        it 'should pass' do
            test_result = job.run_job(my_param)
            expect(test_result[0]["job1"]).to eq("run")
        end
     end
  end
end

Using before block

describe Job do
  let(:job) { Job.new }

  describe 'run_job' do
    context 'success' do
        before(:all) do
          @my_param = [{"job1" => "run"}, {"job2" => "run again"}]
        end

        it 'should pass' do
            test_result = job.run_job(@my_param)
            expect(test_result[0]["job1"]).to eq("run")
        end
     end
  end
end

Upvotes: 2

Related Questions