opensource-developer
opensource-developer

Reputation: 3038

RSpec: Using a each loop for similar it blocks

I am writing tests to check if certain end-points return a status of 200.

RSpec.describe 'API -> ' do
  before do
    @token = get_token
  end

  describe 'Status of below end points should be 200 -->' do

    it "/one should return a status code of 200" do
      get("/api/v1/one", params: {
        authentication_token: @token
      })
      expect(response.status).to eql(200)
    end

    it "/two should return a status code of 200" do
      get("/api/v1/two", params: {
        authentication_token: @token
      })
      expect(response.status).to eql(200)
    end

    it "/three should return a status code of 200" do
      get("/api/v1/three", params: {
        authentication_token: @token
      })
      expect(response.status).to eql(200)
    end

  end
end

There are many such end points and i wanted to know if there is more efficient way to write this, something like

RSpec.describe 'API -> ' do
  before do
    @token = get_token
    @end_points = ['one', 'two', 'three', 'four', 'five']
  end

  describe 'Status of below end points should be 200 -->' do
    @end_points.each do |end_point|
      it "/#{end_point} shold returns a status code of 200" do
        get("/api/v1/#{end_point}", params: {
          authentication_token: @token
        })
        expect(response.status).to eql(200)
      end
    end
  end
end

but this does not work and gives an error each called for nil.

Any help with this will be great, Thanks.

Upvotes: 0

Views: 1090

Answers (2)

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230286

John's answer is good, especially if you have more specs per endpoint.

As to your attempt, it was a simple mistake with scoping. Your instance variable is set on one level, but used on another. Set it on the same level.

  describe 'Status of below end points should be 200 -->' do
    end_points = ['one', 'two', 'three', 'four', 'five']
    end_points.each do |end_point|
      it "/#{end_point} shold returns a status code of 200" do
        get("/api/v1/#{end_point}", params: {
          authentication_token: @token
        })
        expect(response.status).to eql(200)
      end
    end
  end

Upvotes: 1

John Ledbetter
John Ledbetter

Reputation: 14173

What you can use is a shared example.


shared_examples "returns 200 OK" do |endpoint|
 let(:token) { get_token }

 it "should return a status code of 200" do
   get(endpoint, params: { authentication_token: token })
   expect(response.status).to eql(200)
 end
end

describe '..' do
  include_examples 'returns 200 OK', '/api/endpoint/1'
  include_examples 'returns 200 OK', '/api/endpoint/2'
end

Upvotes: 3

Related Questions