简体   繁体   中英

Using rspec to test an API endpoint

I have this api endpoint wot get all the blogs from my database that works id the user pass an api_key. This works correctly and now I'm trying to testing this endpoint.

Routes:

Rails.application.routes.draw do
  get 'blogs', to: 'blogs#index'
end

Blogs controller:

class BlogsController < ApplicationController
  def index
    if params[:api_key]
      user = User.find_by(api_key: params[:api_key])
      if user.present?
        @blogs = Blog.all
        return render json: @blogs, status: :ok   
      end         
    end
    render json: { error: "Unauthorized!" }, status: :bad_request
  end
end

I'm new to rspec and tests in general, I watched a couple videos and tutorials and this is what I have so far:

spec/requests/blogs_spec.rb

require 'rails_helper'

RSpec.describe 'Blogs API', type: :request do
  let!(:blogs) { Blog.limit(10) }

  describe 'GET /blogs' do
    before { get '/blogs' }
    
    it 'returns status code 400' do
      expect(response).to have_http_status(400)
    end

    context 'when the request is valid' do
      before { get '/blogs', params: { api_key: '123123'} }

      it 'returns status code 400' do
        expect(response).to have_http_status(200)
      end
    end
  end
end

I can't seem to make the last test work and I don't know why. My guess is that I'm not passing api_key correctly, but I don't know how

 1) Blogs API GET /blogs when the request is valid returns status code 400
     Failure/Error: expect(response).to have_http_status(200)
       expected the response to have status code 200 but it was 400
     # ./spec/requests/blogs_spec.rb:28:in `block (4 levels) in <top (required)>'

Ok, so accordingly to your question + comments, I can assume you are running your tests within test environment, but you are expecting to find a User existing in development database.

FactoryBot

You might wanna use FactoryBot to create records for your testing suite.

Add to your Gemfile:

group :development, :test do
  gem 'factory_bot_rails'
end

In rails_helper.rb , add:

RSpec.configure do |config|
  config.include FactoryBot::Syntax::Methods
end

Now you should create your User factory. Create a new file spec/factories/user.rb with the following:

FactoryBot.define do
  factory :user do
    api_key { '123123' }
    # You should define every any other required attributes here so record can be created
  end
end

Finally, in your spec file:

    ....

    context 'when the request is valid' do
      before { get '/blogs', params: { api_key: user.api_key} }
      let!(:user) { create(:user) }

      it 'returns status code 200' do
        expect(response).to have_http_status(200)
      end
    end

    ...

Now your test should pass. Notice that in testing database there is no Blog created also, so:

let!(:blogs) { Blog.limit(10) }

Will return an empty array. You will need to create a Blog factory too, and create blogs like:

let!(:blogs) { create_list(:blog, 2) }

Bonus

As soon as you start improving your tests, you may wanna take a look at Faker and Database Cleaner for ActiveRecord

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM