如何在删除中传递ID:在Rails中销毁?

时间:2017-09-20 01:18:25

标签: ruby-on-rails testing rspec

这非常简单,但我无法弄清楚如何让测试通过。

我有一个friendships控制器,我想测试(我正在构建类似于this railscast的Rails应用程序)。它适用于localhost。这是我创建的测试。 POST #create过去了。

require 'rails_helper'

RSpec.describe FriendshipsController, type: :controller do
  login_user

  before :each do
    @friend1 = FactoryGirl.create(:user)
  end

  describe "POST #Create" do
    it "adds new friend" do
      expect {
        post :create, params: { friend_id: @friend1.id}
      }.to change(Friendship, :count).by(1)
    end
  end

  describe "DELETE #destroy" do
    it "removes a friend =(" do
      expect {
        delete :destroy, id: @friend1.id
      }.to change(Friendship, :count).by(1)
    end
  end

end

这是实际的控制器:

class FriendshipsController < ApplicationController
  def create
    @friendship = current_user.friendships.build(friend_id: params[:friend_id])
    if @friendship.save
      flash[:notice] = "New friend added!"
      redirect_to root_url
    else
      flash[:error] = "Error adding friend"
      redirect_to root_url
    end
  end

  def destroy
    @friendship = current_user.friendships.find(params[:id])
    @friendship.destroy
    flash[:notice] = "Remove friendship"
    redirect_to current_user
  end
end

我还确保routes.rb有友谊:resources :friendships

我遇到的问题是传递ID。我无法弄清楚如何传递id参数。我认为这与我的工厂有关......?

  1) FriendshipsController DELETE #destroy removes a friend =(
     Failure/Error: @friendship = current_user.friendships.find(params[:id])

     ActiveRecord::RecordNotFound:
       Couldn't find Friendship with 'id'=159 [WHERE "friendships"."user_id" = $1]

我搜索其他SO destroy相关帖子,例如this onethis,但它们与我的情况不同。

如何为我的销毁行动传递ID参数?

编辑:(Source

module ControllerMacros
  def login_user
    before(:each) do
      @request.env["devise.mapping"] = Devise.mappings[:user]
      user = FactoryGirl.create(:user)
      #user.confirm! # or set a confirmed_at inside the factory. Only necessary if you are using the "confirmable" module
      sign_in user
    end
  end
end

如下面的回答所示,我做了:

describe "DELETE #destroy" do
    it "removes a friend =(" do
      friendship = user.friendships.create!(friend_id: @friend1.id)
      expect {
        delete :destroy, id: friendship.id
      }.to change(Friendship, :count).by(1)
    end
  end

但它现在返回此错误:

FriendshipsController DELETE #destroy removes a friend =(
     Failure/Error: friendship = user.friendships.create!(friend_id: @friend1.id)

     NameError:
       undefined local variable or method `user' for #<RSpec::ExampleGroups::FriendshipsController::DELETEDestroy:0x007fee1ce68c70>

1 个答案:

答案 0 :(得分:1)

当您正在寻找友谊时,而不是控制器中的用户,您需要先创建友谊。在此之前,您还需要知道要登录的用户。请先尝试发送:

module ControllerMacros
  def login_user(user)
    before(:each) do
      @request.env["devise.mapping"] = Devise.mappings[:user]
      user ||= FactoryGirl.create(:user)
      sign_in user
    end
  end
end

现在测试看起来像这样:

let(:current_user) { FactoryGirl.create(:user) }
login_user(current_user)

describe "DELETE #destroy" do
  it "removes a friend =(" do
    friendship = current_user.friendships.create!(friend_id: @friend1.id)
    expect {
      delete :destroy, id: friendship.id
    }.to change(Friendship, :count).by(1)
  end
end

你现在应该好好去。