Subject
Manipulate subject?
just give your subject a name
RSpec.describe Api::V1::LoginController, type: :controller do
render_views
describe "POST#create" do
let!(:user){ create(:user) }
context "valid credentials" do
let(:data){ {format: :json, login: { account: user.account, password: user.password }} }
let(:expected_json){ { user: { email: user.account, auth_token: user.auth_token }}}
subject(:login) { post :create, data }
it { expect(login).to have_http_status(:created) }
it { expect(JSON.parse(login.body, symbolize_names: true)).to eq expected_json }
end
end
end
Using subject + its
RSpec.describe Api::V1::ActiveUserController, type: :controller do
describe "GET#index" do
context "with valid activation code" do
let(:user){ create(:user) }
let(:data){ { activation_code: user.activation_code } }
subject { get :index, data }
it { is_expected.to have_http_status(:ok) }
its(:body) { is_expected.to have_content /Congratulations! You have successfully activated your account/ }
end
context "with expired activation code" do
let(:user){ create(:user, activation_code_expired_at: Date.yesterday) }
let(:data){ { activation_code: user.activation_code } }
subject{ get :index, data }
it { is_expected.to have_http_status(:bad_request) }
its(:body) { is_expected.to have_content /Expired active code/ }
end
context "invalid activation code" do
let(:user){ create(:user, activation_code_expired_at: Date.yesterday) }
let(:data){ { activation_code: "invalid_activation_code" } }
subject{ get :index, data }
it { is_expected.to have_http_status(:bad_request) }
its(:body) { is_expected.to have_content /Invalid activation code/ }
end
end
end
Subject!
RSpec.describe Api::V1::ActiveUserController, type: :controller do
describe "GET#index" do
context "with valid activation code" do
let(:user){ create(:user, auth_token: nil) }
let(:data){ { activation_code: user.activation_code } }
subject { get :index, data }
it { is_expected.to have_http_status(:ok) }
its(:body) { is_expected.to have_content /Congratulations! You have successfully activated your account/ }
it { expect(User.find(user.id).auth_token).to be_truthy }
end
end
end
# Failure/Error: it { expect(User.find(user.id).auth_token).to be_truthy}
# expected: truthy value
# got: nil
Use subject!
to ask rspec to call the block before any example
subject! { get :index, data }
Use memoized subject
subject(:abc) { }
subject!(:abc) { }