【问题标题】:Expected response to be a <redirect>, but was <200> when using get :edit预期响应为 <redirect>,但在使用 get 时为 <200> :edit
【发布时间】:2015-02-15 02:53:55
【问题描述】:

我在 rspec 中重定向和测试时遇到问题

当我使用 get 方法时,我遇到了测试未通过的问题,但是当我使用 put 方法时,相同的代码库是绿色的。我不知道如何解决这个问题,需要帮助以使测试通过。

我得到一个200 HTTP 状态码,但我想获得重定向确认,以便rspec 可以跟踪它。代码基本上需要做的是在尝试使用get http method 编辑产品时将不是产品所有者的登录用户重定向到category_product_url(category, product),并使用闪光灯error: 'You are not allowed to edit this product.'

使用宝石rspec-railsdevisedecent_exposure。 Ruby 2.1.5 和 Rails 4.1.8

实际错误信息:

Failure/Error: expect(response).to redirect_to(category_product_url(category, product))
   Expected response to be a <redirect>, but was <200>

Failure/Error: expect(controller.flash[:error]).to eq 'You are not allowed to edit this product.'
   
   expected: "You are not allowed to edit this product."
        got: nil
   
   (compared using ==)

我的规格

context 'another user is singed in' do
let(:user) { create(:user) }
let(:user2) { build(:user) }
let(:product) { Product.create! valid_attributes }

before do
  sign_in user2
  controller.stub(:user_signed_in?).and_return(true)
  controller.stub(:current_user).and_return(user2)
  controller.stub(:authenticate_user!).and_return(user2)
  product.user = user
end

describe 'GET edit' do
  describe 'with valid params' do
    it 'redirects to product page' do
      get :edit, { id: product.to_param, category_id: category.to_param }
      expect(response).to redirect_to(category_product_url(category, product))

    end

    it 'renders error message' do
      get :edit, { id: product.to_param, category_id: category.to_param }
      expect(controller.flash[:error]).to eq 'You are not allowed to edit this product.'
    end
  end
end

我的控制器

before_action :authenticate_user!, only: [:new, :edit, :update, :destroy, :create]
expose(:category)
expose(:products)
expose(:product)

def edit
end

def update
  if product.user == current_user
    if self.product.update(product_params)
      redirect_to category_product_url(category, product), notice: 'Product was successfully updated.'
    else
      render action: 'edit'
    end
  else
     redirect_to category_product_url(category, product), flash: { error: 'You are not allowed to edit this product.' } 
  end
end

private
def product_params
  params.require(:product).permit(:title, :description, :price, :category_id, :user_id)
end

奇怪的是,put 方法在相同的update 操作下运行良好。以下规格正在通过

describe 'PUT update' do
  describe 'with valid params' do
    it 'redirects to product page' do
      put :update, { id: product.to_param, product: { 'title' => 'MyString' }, category_id: category.to_param }
      expect(response).to redirect_to(category_product_url(category, product))
    end

    it 'does not update product' do
      put :update, { id: product.to_param, product: { 'title' => 'MyNewString' }, category_id: category.to_param }
      expect(controller.product.title).to_not eq 'MyNewString'
    end

    it 'renders error message' do
      put :update, { id: product.to_param, product: { 'title' => 'MyString' }, category_id: category.to_param }
      expect(controller.flash[:error]).to eq 'You are not allowed to edit this product.'
    end
  end
end

【问题讨论】:

  • 我认为可以使用 put 方法进行更新操作,因为您要在编辑后更新记录。
  • 这不是问题,正如我提到的,这个测试通过了。我需要做的是让get 测试通过而不破坏put 测试。
  • 这有点令人困惑。控制器中没有“编辑”代码。为什么你会期望调用 get "edit" 除了渲染编辑页面(并返回 200)来做任何事情?
  • 这就是decent_exposure gem 的工作原理

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


【解决方案1】:

decent_exposuredevise 的工作方式是,您需要首先调用 before_action 方法,将您选择的私有方法传递给该方法。

对于这个特定的例子,你的控制器应该包含这个

before_action :author!, only: [:edit, :update]

还有一个私有方法过滤器

def author!
  unless self.product.user == current_user
    redirect_to category_product_url(category, product),
      flash: { error: 'You are not allowed to edit this product.' }
  end
end

这样您的get http requestsput http requests 就通过了规范。

【讨论】:

    【解决方案2】:

    试试这个

    expect(:get => "/products/1/edit").to route_to(:controller => "controller_name", :action => "action_name")
    

    希望这会奏效。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多