RSpec: 在没有分配方法的情况下断言成功创建请求

RSpec: Assert successful create request without assigns method

我在 Rails 控制器中的 create 方法中有此代码:

if @product.save
  format.html { redirect_to @product, notice: 'Product was successfully created.' }

为了测试这段代码,我在 RSpec 文件中有这样的期望:

expect(response).to redirect_to(assigns(:product))

使用 assigns 是 deprecated/has 被移动到 gem 坦率地说,我不关心 @product@my_product 是否已在控制器。其实我只是想知道我是否被重定向到 /products/<some-id>。有(推荐的)方法吗?

GitHub Issue 解释了为什么 assigns 被弃用

Testing what instance variables are set by your controller is a bad idea. That's grossly overstepping the boundaries of what the test should know about. You can test what cookies are set, what HTTP code is returned, how the view looks, or what mutations happened to the DB, but testing the innards of the controller is just not a good idea.

您可以使用 have_http_status 匹配器

测试响应状态代码
expect(response).to have_http_status(:success)

如果你想渲染新的你需要添加 gem 'rails-controller-testing' 到你的 Gemfile.

看完你的评论后,我猜你的动作#create 是这样的:

  def create
    @product = Product.new(product_params)

    respond_to do |format|
      if @product.save
        format.html { redirect_to @product, notice: 'Product was successfully created.' }
        format.json { render :show, status: :created, location: @product }
      else
        format.html { render :new }
        format.json { render json: @product.errors, status: :unprocessable_entity }
      end
    end
  end

你可以做这样的测试:

  describe 'POST /products' do
    context 'when everithing is ok' do
      it 'returns the product' do
        post products_url, params: { product: { description: 'lorem ipsum', title: 'lorem ipsum' } }

        expect(response).to redirect_to(product_url(Product.last))
      end
    end

    context 'when something worong' do
      it 'redirect to new' do
        post products_url, params: { product: { description: 'lorem ipsum' } }

        expect(response).to render_template(:new)
      end
    end
  end