通过追随者/友谊进行RSpec测试的用户很多

时间:2016-04-10 19:05:06

标签: ruby-on-rails testing rspec has-many-through

我通过以下链接http://railscasts.com/episodes/163-self-referential-association启发了自己,但是rspec测试并不容易。

用户模型:

class User < ActiveRecord::Base

  # Associations
  has_many :followerships
  has_many :followers, :through => :followerships
  has_many :inverse_followerships, :class_name => "Followership", :foreign_key => "follower_id"
  has_many :inverse_followers, :through => :inverse_followerships, :source => :user
end

关注模式:

class Followership < ActiveRecord::Base
  belongs_to :user
  belongs_to :follower, :class_name => "User"
end

关注工厂:

FactoryGirl.define do
  factory :followership do
    user_id 1
    follower_id 1
  end
end

关注者控制器:

class FollowershipsController < InheritedResources::Base
  def create
    @followership = current_user.followerships.build(:follower_id => params[:follower_id])
    if @followership.save
      flash[:notice] = "Following."
      redirect_to root_url
    else
      flash[:error] = "Unable to follow."
      redirect_to root_url
    end
  end

  def destroy
    @followership = current_user.followerships.find(params[:id])
    @followership.destroy
    flash[:notice] = "Removed followership."
    redirect_to current_user
  end
end

folowerships控制器规范(这是完全错误的):

require 'rails_helper'

describe FollowershipsController do
  let!(:followership) { create(:followership) }
  let!(:follower) { followership.follower }
  let!(:user) { create(:user) }

  before do
    sign_in :user, user
  end

  describe "#create" do
    it "saves the followership" do
      post :create, followership: { follower_id: follower }

      expect(response).to redirect_to(root_path)
      expect(assigns(:followership).followership.followers).to eq(user)
      expect(flash[:notice]).to eq("Following.")
    end

    it "fails to save followership" do
      expect(post :create, followership: { follower_id: follower }).to redirect_to(root_path)
      expect(flash[:notice]).to eq("Unable to follow.")
    end
  end

  describe "#destroy" do
    it "deletes the followership" do
      expect {
        delete :destroy, id: follower
      }.to change(Followership, :count).by(-1)

      expect(flash[:notice]).to eq("Removed followership.")
    end
  end

end

来自关注者控制器Rspec的错误

FollowershipsController
  #destroy
    deletes the followership (FAILED - 1)
  #create
    saves the followership (FAILED - 2)
    fails to save followership (FAILED - 3)

Failures:

  1) FollowershipsController#destroy deletes the followership
     Failure/Error: delete :destroy, id: follower

     ActionController::UrlGenerationError:
       No route matches {:action=>"destroy", :controller=>"followerships", :id=>nil}

  2) FollowershipsController#create saves the followership
     Failure/Error: expect(assigns(:followership).followership.followers).to eq(user)

     NoMethodError:
       undefined method `followership' for #<Followership:0x00000109f69780>

  3) FollowershipsController#create fails to save followership
     Failure/Error: expect(flash[:notice]).to eq("Unable to follow.")

       expected: "Unable to follow."
            got: "Following."

       (compared using ==)

感谢您的帮助:)

1 个答案:

答案 0 :(得分:2)

let命令使用延迟评估,因此在调用之前不会实际创建这些记录。使用let!语法确保在测试运行之前创建它们:

  let!(:followership) { create(:followership) }
  let!(:follower) { followership.follower }
  let!(:user) { create(:user) }

如果对于该对用户尚未存在,则确保您的验证仅允许创建以下用户:

class Followership < ActiveRecord::Base
   validates_uniqueness_of :user_id, scope: :follower_id

此外,由于follower不一定有followership,因此无法保证user / user关系属于idassigns 1}} 1。

最后,assigns(:followership)是一种方法,因此语法应为assigns[:followership]而不是Notice: Undefined index: soft_id in C:\xampp\htdocs\SLR\Update S110 PC01.php on line 14 Notice: Undefined index: soft_name in C:\xampp\htdocs\SLR\Update S110 PC01.php on line 15 Notice: Undefined index: installed_date in C:\xampp\htdocs\SLR\Update S110 PC01.php on line 16 Notice: Undefined index: expiry_date in C:\xampp\htdocs\SLR\Update S110 PC01.php on line 17 Notice: Undefined index: product_key in C:\xampp\htdocs\SLR\Update S110 PC01.php on line 18 Fatal error: Uncaught Error: Call to undefined function mysql_query() in C:\xampp\htdocs\SLR\Update S110 PC01.php:22 Stack trace: #0 {main} thrown in C:\xampp\htdocs\SLR\Update S110 PC01.php on line 22