HyperMeat
HyperMeat

Reputation: 91

Rspec request spec's empty response

I'm trying to write a request spec for my first Rails app, but the response object is nil. Rspec is still dark magic to me, so I may be missing something really basic, but given the example here I figured this would work. When I run the Rails server, I can authenticate over cURL, and my controller spec works fine.

Here's my request spec:

# spec/requests/tokens_request_spec.rb
require 'rails_helper'

RSpec.describe Api::V1::TokensController, type: :request do
  context "getting the token" do
    let(:user) { create(:user) }

    it 'status code is 2xx' do
      post "/api/v1/login", { auth: { email: user.email, password: user.password } }, { accept: "application/json" }
      expect(response).to have_http_status(:success)
    end
  end
end

Here's my controller:

# app/controllers/api/v1/tokens_controller.rb
class Api::V1::TokensController < ApplicationController
  def create
    user = User.find_by(email: user_params["email"])
    return render json: { jwt: Auth.issue(user: user.id) } if user.authenticate(user_params["password"])
    render json: { message: "Invalid credentials" }, status: 401
  end

  private

  def user_params
    params.require(:auth).permit(:email, :password)
  end
end

Here's my test output:

Failures:

  1) Api::V1::TokensController getting the token status code is 2xx
     Failure/Error: expect(response).to have_http_status(:success)
       expected the response to have a success status code (2xx) but it was
     # ./spec/requests/tokens_request_spec.rb:13:in `block (3 levels) in <top (required)>'
     # ./spec/spec_helper.rb:27:in `block (3 levels) in <top (required)>'
     # ./spec/spec_helper.rb:26:in `block (2 levels) in <top (required)>'

Any help is greatly appreciated.

Upvotes: 3

Views: 3139

Answers (1)

HyperMeat
HyperMeat

Reputation: 91

Ok, I've got this working.

it 'status code is 200' do
   post "/api/v1/login", { auth: { email: user.email, password: user.password } }, { accept: "application/json" }
      expect(last_response.status).to eq(200)
end

I'm not sure why I need to use last_response or how I should have known that (especially since the official documentation tells me I should use response), but there it is.

Upvotes: 2

Related Questions