Rspec规格控制器

时间:2019-03-11 20:23:05

标签: ruby-on-rails ruby rspec rspec-rails

我不知道如何测试这样的代码,我想在没有Factory Bot的情况下进行测试,因为这只是示例:

class V1::ForgotPasswordsController < V1::BaseController
  skip_before_action :authenticate_user!

  expose(:verified_object) { verifier.verify(params[:token]) }
  expose(:user) { User.find_by_email(params[:email] || verified_object.first) }
  expose(:accounts) { User.by_email(verified_object.first) }

  def create
    if user
      verify = verifier.generate([user.email, 1.hour.from_now])
      UserMailer.forgot_password(user, verify).deliver_later
      render json: { message: I18n.t('forgot_password.send_instructions') }, status: :accepted
    else
      render json: { message: I18n.t('forgot_password.error_email') }, status: :unprocessable_entity
    end
  end

  def update
    if token_valid?
      return render json: { message: I18n.t('forgot_password.updated') }, status: :accepted unless update_passwords.include?(false)

      render json: { message: I18n.t('forgot_password.error_password') }, status: :unprocessable_entity
    else
      render json: { message: I18n.t('forgot_password.error_token') }, status: 400
    end
  end

结束

1 个答案:

答案 0 :(得分:1)

这里有一些方法,我看不到它们来自哪里,可以进行适当的存根,但是您可能想要一个与之非常接近的方法,它可以测试对请求有意义的每个代码路径,而且还有副作用(发送电子邮件) :

require "spec_helper"

describe "V1::ForgotPasswordsController" do
  let(:user) { User.create(email: "user@example.com") }

  describe "#create" do
    context "with a valid user" do
      it "sends an email to the user and acknowledges the request as accepted" do
        expect(UserMailer).to receive(:forgot_password).with(user, anything).and_call_original
        post v1_create_path, params: { email: user.email }
        expect(response).to be_accepted
        expect(JSON.parse(response.body)[:message]).to eq I18n.t("forgot_password.send_instructions")
      end
    end

    context "without a valid user" do
      it "rejects the request" do
        post v1_create_path, params: { email: "not_user@example.com" }
        expect(response).to be_unprocessable_entity
        expect(JSON.parse(response.body)[:message]).to eq I18n.t("forgot_password.error_email")
      end
    end
  end

  describe "#update" do
    context "with valid token" do
      before { allow_any_instance_of(V1::ForgotPasswordsController).to receive(:token_valid?).and_return(true) }

      context "with update_passwords not including false" do
        before { allow_any_instance_of(V1::ForgotPasswordsController).to recieve(:update_passwords).and_return([]) }

        it "acknowledges the request as accepted" do
          put v1_update_path(user), params: { email: user.email }
          expect(response).to be_accepted
          expect(JSON.parse(response.body)[:message]).to eq I18n.t("forgot_password.updated")
        end
      end

      context "with update_passwords including false" do
        before { allow_any_instance_of(V1::ForgotPasswordsController).to recieve(:update_passwords).and_return([false]) }

        it "rejects the request" do
          put v1_update_path(user), params: { email: user.email }
          expect(response).to be_unprocessable_entity
          expect(JSON.parse(response.body)[:message]).to eq I18n.t("forgot_password.error_password")
        end
      end
    end

    context "with an invalid token" do
      before { allow_any_instance_of(V1::ForgotPasswordsController).to receive(:token_valid?).and_return(false) }

      it "rejects the request as bad" do
        put v1_update_path(user), params: { email: user.email }
        expect(response).to be_bad_request
        expect(JSON.parse(response.body)[:message]).to eq I18n.t("forgot_password.error_token")
      end
    end
  end
end