【问题标题】:Rspec: Using factories in other factoriesRspec:在其他工厂使用工厂
【发布时间】:2017-02-18 03:34:38
【问题描述】:

我正在编写一个创建方法的成本,该方法将在帖子中添加评论。

评论属于用户和帖子。并且帖子属于用户。

当我运行测试时,我收到一个验证错误,提示用户名和电子邮件已被使用。我已经尝试在我的工厂和测试中使用 build 和 build_stubbed ,但它们都不起作用。我认为这与我使用 create 的事实有关,但我并不完全确定。

任何建议将不胜感激

这是我的工厂:

users.rb

FactoryGirl.define do
factory :user do
    username "test_user"
    email "test_user@email.com"
    password "password"
end

factory :user_2, class: User do
    username "test_user_2"
    email "test_user_2@email.com"
    password "password"
end

factory :invalid_user, class: User do
    username ""
    email ""
    password ""
end
end

outlets.rb

FactoryGirl.define do
  factory :outlet do
    category "vent"
    title "MyString"
    body "MyText"
    urgency 1
    user factory: :user
  end

  factory :outlet_2, class: Outlet do
    category "rant"
    title "MyString_2"
    body "MyText_2"
    urgency 2
    user factory: :user_2
  end

  factory :invalid_outlet, class: Outlet do
    category "qualm"
    title ""
    body ""
    urgency 3
    user factory: :user
  end
end

comments.rb

FactoryGirl.define do
  factory :comment do
    body "This is a comment"
    user factory: :user
    outlet factory: :outlet_2
  end

  factory :invalid_comment, class: Comment do
    body "This is a comment"
    user nil
    outlet nil
  end  
end

这是我的测试:

describe 'create' do
        context 'with valid attributes' do

            let(:outlet) { FactoryGirl.create(:outlet) }
            let(:valid_comment_params) { FactoryGirl.attributes_for(:comment) }

            it "creates a new comment" do
                expect { post :create, params: { id: outlet, :comment => valid_comment_params } }.to change(Comment, :count).by(1)
            end
        end
    end

这是我的模型:

class Comment < ApplicationRecord
  belongs_to :user
  belongs_to :outlet

  validates :body, :user, :outlet, presence: true
  validates :body, length: { in: 1..1000 }
end

class Outlet < ApplicationRecord
  belongs_to :user
  has_many :comments

  validates :category, :title, :body, :urgency, :user, presence: true
  validates :title, length: { in: 1..60 }
  validates :body, length: { in: 1..1000 }
  validates :urgency, numericality: { only_integer: true, greater_than_or_equal_to: 1, less_than_or_equal_to: 10 }
  validates :category, inclusion: { in: ['vent', 'rant', 'qualm'] }
end

class User < ApplicationRecord
    has_many :outlets
    has_many :comments

    validates :username, :email, :encrypted_password, presence: true
    validates :username, :email, uniqueness: true
    validates :password, length: { in: 5..30 }
  # Include default devise modules. Others available are:
  # :lockable, :timeoutable 
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable, :omniauthable
end

【问题讨论】:

  • 您介意发布您的模型代码(特别是验证)吗?这将有助于指导答案。
  • 好的,我刚刚用模型代码编辑了

标签: ruby-on-rails ruby rspec factory-bot


【解决方案1】:

所以这里的问题是您一直尝试使用与您刚刚创建另一个用户相同的电子邮件和用户名创建一个用户。为了在您的工厂中避免这种情况,您应该努力使价值观动态化。由于目前的主要问题是唯一性验证,让我们从这些开始。

factory :user do
  sequence(:username) { |n| "test_user#{n}" }
  sequence(:email)    { |n| "test_user#{n}@email.com" }
  password "password"
end

这样,您可以使用同一个工厂创建 2 个不同的用户

user = FactoryGirl.create :user
user_2 = FactoryGirl.create :user

【讨论】:

  • 当我尝试这个时,我要么得到“用 id= 找不到”,要么它应该将计数更改为 1,但它更改为 0
  • 在你的测试中你想做expect { post :create, params: { :comment =&gt; valid_comment_params } }.to change(Comment, :count).by(1) 你不需要id 值,因为你还没有创建对象(它没有id,直到它被持久化)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-18
  • 2021-08-06
  • 1970-01-01
  • 2016-03-01
  • 1970-01-01
相关资源
最近更新 更多