GOLDY AGARWAL
GOLDY AGARWAL

Reputation: 15

How to write Rspec for APIs

I have the following code in my API file

    class TransactionStatus < Grape::API
        helpers ::PushAPIv1::NamedParams

        post '/transaction/status' do
          Rails.logger.warn "#{params.to_xml}"
             // some piece of code
        end
      end

I tried to write Rpsec for this condition but not getting any success in my coverage report. The Spec I tried to write is as below

require 'rails_helper'
RSpec.describe Transaction, type: :request do
  context 'check Transaction Status' do
    it 'should log an info message' do
      expect(Rails.logger).to receive(:warn).with("#{params.to_xml}")
    end

    it 'should raise Transaction Not Found Error if invalid transaction' do
        transaction = FactoryGirl.build(:transaction, state: 'processing', gateway_message: 'success', ref_code: '1qqqq1')
        p transaction.ref_code
        expect { Transaction.find_by_ref_code('q1111q').should eq transaction }.to raise_error()
    end
  end
end

Upvotes: 0

Views: 327

Answers (1)

P&#233;ha
P&#233;ha

Reputation: 2933

Well, if what you're trying to achieve is coverage of your POST /transaction/status endpoint, then... you need to reach for the endpoint in your specs, which you're not doing at the moment.

it 'should log an info message' do
  expect(Rails.logger).to receive(:warn).with("#{params.to_xml}")
end

Here you expect Rails.logger to receive warn message. But you need to trigger something that should call Rails.logger.warn for the spec to pass.

it 'should raise Transaction Not Found Error if invalid transaction' do
  transaction = FactoryGirl.build(:transaction, state: 'processing', gateway_message: 'success', ref_code: '1qqqq1')
  expect { Transaction.find_by_ref_code('q1111q').should eq transaction }.to raise_error()
end

About this spec: you're mixing expect and should syntaxes in a manner that's hardly understandable. Plus you're just using ActiveRecord methods, and never call your actual API endpoint. That's why you don't get any code coverage.


In the end, what you should do to get proper coverage of your endpoint is actually calling it. This could be done in a before :each block for instance, or even in each of your spec, like this:

describe 'transaction/status' do
  before :each do
    post 'path/to/api/transaction/status'
    # post 'path/to/api/transaction/status', params: { some: params }
    # post 'path/to/api/transaction/status', headers: { some: headers }
  end

  it '...' do
    expect( response ).to ...
  end
end

You get the idea. You can check out RSpec Rails 3.7 - Request specs for more details and examples.

Upvotes: 1

Related Questions