Rspec强大的合并与合并

时间:2015-08-12 01:12:30

标签: ruby-on-rails ruby rspec

所以我正在尝试为我正在研究的项目编写一些测试。 控制器

  def update
    @project = Project.find_by(id: params[:id])
    current_tags = @project.project_tags
    current_tags.destroy_all
    @project.assign_attributes(project_params)
    tags = params[:tags].split(',')
    if @project.save
      tags.each do |tag|
        valid_tag = Tag.find_by(name: tag.strip.capitalize)
        if valid_tag
          @project.tags << valid_tag
        else
          flash[:notice] = "That tag does not exist"
        end
      end
      redirect_to @project, notice: "Project updated successfully"
    else
      flash.now[:errors] = @project.errors.full_messages
      render :edit
    end
  end

在我的模特中

class Project < ActiveRecord::Base

  belongs_to :creator, class_name: "User"
  has_many :project_tags
  has_many :tags, through: :project_tags
  has_many :collaborations
  has_many :collaborators, through: :collaborations, class_name: "User"

  validates :creator, presence: true
  validates :title, presence: true
  validates :description, presence: true
  validates :status, presence: true
  validates :skills_desired, presence: true

  def tags_for_edit
    tags.map { |tag| tag.name }.join(', ')
  end

  def collaborators_with_status(status)
    User.joins(:collaborations)
    .select("collaborations.project_id, collaborations.status, users.*")
    .where("status='#{status}' AND project_id=#{self.id}")
  end

  def collaborations_with_status(status)
    Collaboration.where("status='#{status}' AND project_id=#{self.id}")
  end

end

Rspec我正在尝试写

  describe 'PATCH #update' do
    context 'while not logged in' do
      xit 'redirects user back to the root path' do
        get :patch, id: project
        expect(response).to redirect_to root_path
      end
    end
  end

private

  def project_params
    params.require(:project).permit(:title, :description, :start_date, :end_date, :status, :skills_desired, :repo_link).merge(creator_id: session[:user_id])
  end

我与Factory Girl的项目工厂

FactoryGirl.define do
  factory :project do
    creator_id 1
    title {Faker::Hacker.adjective}
    description {Faker::Hacker.say_something_smart}
    start_date {Faker::Date.between(2.days.ago, Date.today)}
    end_date {Faker::Date.forward(20)}
    status 'planning'
    skills_desired 'be smart'

    factory :invalid_project do
      title nil
    end

  end
end

最后我得到的错误

  1) ProjectsController PATCH #update while not logged in redirects user back to the root path
     Failure/Error: let(:project) {FactoryGirl.create(:project)}
     ActiveRecord::RecordInvalid:
       Validation failed: Creator can't be blank

所以我假设问题在于我的控制器在我强大的参数中我将创建者ID合并到项目中。我不确定进行测试的正确语法是什么。我一直在网上搜索一段时间,但找不到任何东西。会喜欢这个的帮助。感谢

2 个答案:

答案 0 :(得分:2)

我相信你得到的当前错误

 ActiveRecord::RecordInvalid:
    Validation failed: Creator can't be blank

是因为你在这里有这一行

validates :creator, presence: true

因此,您无法在未指定有效创建者记录ID的情况下创建项目工厂,并且创建者记录必须首先存在。我建议你为Creator工厂做这样的事情。通过这种方式,您可以确信存在具有有效ID的创建者记录,以便在项目记录的creator_id属性中使用

FactoryGirl.define do
    factory :creator do
      some_attribute "some attribute"
      after(:create) do |creator, evaluator|
        creator.projects << FactoryGirl.create(:project, creator_id: creator.id)
      end
    end
  end

答案 1 :(得分:1)

经过一些实验和朋友的一点帮助后,我能够在项目工厂中添加协作者ID:

FactoryGirl.define do
  factory :project do
    association :creator, factory: :user
    title {Faker::Hacker.adjective}
    description {Faker::Hacker.say_something_smart}
    start_date {Faker::Date.between(2.days.ago, Date.today)}
    end_date {Faker::Date.forward(20)}
    status 'planning'
    skills_desired 'be smart'

    factory :invalid_project do
      title nil
    end

  end
end

我添加的字段是关联

association :creator, factory: :user

这允许我使用我在工厂内设置的关联。感谢您抽出宝贵时间帮助我。 @MilesUA你的解决方案也有效,但我设法提出的解决方案帮助我将它保存到一家工厂。再次感谢