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

its for RSpec 3 has been extracted from rspec-core 2.x, add gem rspec-its to your Gemfile before use it

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) { }

Reference

results matching ""

    No results matching ""