Ruby,factorybot错误复制与rspec

2sbarzqh  于 12个月前  发布在  Ruby
关注(0)|答案(2)|浏览(133)

我在我的应用程序中遇到了一个错误。我正在用RSpec和我的PagesController测试来测试它,在开始时:

let(:user) { create(:user, favorite_category: "Elettronica") }

字符串
我得到错误:

Failure/Error:
  factory :user , class: User do
    email { 'te[email protected]' }
    password { 'password' }
    full_name { 'a b' }
    uid { '12345' }
    avatar_url { 'http://example.com/avatar.png' }
    role { 0 }
    favorite_category { "moda" }
  end


我有3个工厂,所有相关的用户,在文件夹spec/factories的不同文件。
我被卡住了,我不明白问题出在哪里。
我的用户模型:

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and 
   :omniauthable
    devise :omniauthable, :database_authenticatable, :registerable,
     :recoverable, :rememberable, :validatable, omniauth_providers: 
    [:google_oauth2]
    
attr_accessor :current_password

has_one_attached :avatar

def avatar_thumbnail
  if avatar.attached?
  avatar.variant(resize: "150x150!").processed
 else
  "/assets/default_profile.jpg"
 end  
end

has_many :messages
has_many :reviews
has_many :researches
has_many :active_relationships, class_name: "Relationship",
                            foreign_key: "follower_id",
                            dependent: :destroy
has_many :following, through: :active_relationships, source: 
:followed    
has_many :passive_relationships, class_name: "Relationship",
                             foreign_key: "followed_id",
                             dependent: :destroy
has_many :followers, through: :passive_relationships, source: 
:follower

def self.from_omniauth(auth)
   where(provider: auth.provider, uid: auth.uid).first_or_create do 
   |user|
   user.email = auth.info.email
   user.password = Devise.friendly_token[0, 20]
   user.full_name = auth.info.name # assuming the user model has a 
   name
   user.avatar_url = auth.info.image # assuming the user model has an 
   image
  # If you are using confirmable and the provider(s) you use validate 
  emails,
  # uncomment the line below to skip the confirmation emails.
  # user.skip_confirmation!
  end
  end

def admin?
 role == 1  # Supponiamo che tu abbia un campo 'role' nel tuo modello 
 User
end

def moderator?
 role == 2  # Supponiamo che tu abbia un campo 'role' nel tuo modello 
 User
end
**strong text**
def follow(other_user)
 active_relationships.create(followed_id: other_user.id)
end

# Unfollows a user.
def unfollow(other_user)
 active_relationships.find_by(followed_id: other_user.id).destroy
 end

# Returns true if the current user is following the other user.
def following?(other_user)
  following.include?(other_user)
end
end`


工厂用户

FactoryBot.define do
 factory :user do
  email { '[email protected]' }
  password { 'password' }
  full_name { 'John Doe' }
  uid { '12345' }
  avatar_url { 'http://example.com/avatar.png' }
  role { 0 }
  favorite_category { "Elettronica" }
end
end


pages_spec:

require 'rails_helper'
require "./spec/factories/user.rb"

RSpec.describe PagesController, type: :controller do

let(:user) { create(:user, favorite_category: "Elettronica") }

describe "GET #home" do
it "returns a successful response" do
  get :home
  expect(response).to be_successful
end

it "assigns the current user" do
  get :home
  expect(assigns(:user)).to eq(user)
end

it "assigns search results if the user has a favorite category" do
  get :home
  expect(assigns(:search_results)).not_to be_nil
end

it "does not assign search results if the user has no favorite category" 
do
  user.update(favorite_category: "nessuna categoria")
  get :home
  expect(assigns(:search_results)).to be_nil
end
end

describe 'GET #search' do
 it 'assigns instance variables and renders the template' do
  get :search, params: {
    keyword: 'lamp',
    sort_order: 'PricePlusShippingLowest',
    minprice: 0,
    maxprice: 100,
    instaexp: 1,
    place: 'US',
    minf: '0',
    maxtime: '10'
  }

  expect(assigns(:users)).to be_a(ActiveRecord::Relation)
  expect(assigns(:keyword)).to eq('lamp')
  expect(assigns(:sort_order)).to eq('PricePlusShippingLowest')
  expect(assigns(:minprice)).to eq(0)
  expect(assigns(:maxprice)).to eq(100)
  expect(assigns(:instaexp)).to eq(1)
  expect(assigns(:place)).to eq('US')
  expect(assigns(:minf)).to eq('0')
  expect(assigns(:maxtime)).to eq('10')

  # Add more expectations for other instance variables as needed

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

  end

describe 'GET #search' do
 it 'assigns a non-empty @search_results' do
  # Stub the external service that is being called in the controller
  allow_any_instance_of(Caller).to receive(:cerca).and_return([
    { 'title' => 'Item 1', 'price' => 10 }
  ])

  get :search, params: {
    keyword: 'lamp',
    sort_order: 'PricePlusShippingLowest',
    minprice: 0,
    maxprice: 100,
    instaexp: 1,
    place: 'US',
    minf: '0',
    maxtime: '10'
  }

  expect(assigns(:search_results)).not_to be_nil
end
end
end


错误是FactoryBot::DuplicateDefinitonError:factory alredy registered:user

6tr1vspr

6tr1vspr1#

你确实分享了完整的错误信息。因此,我只能猜测重复错误发生在email列上,因为电子邮件在大多数应用程序中需要是唯一的。
每次在此行中创建用户时,您的工厂都会创建相同的电子邮件地址:

email { '[email protected]' }

字符串
这意味着你一次只能创建一个记录。但是有些测试可能需要创建两个用户,这样的测试总是会失败。
FactoryBot允许为需要唯一的列创建序列值。您可以通过将email的定义更改为以下内容来启用FactoryBot中的序列:

sequence :email { |n| "test-#{n}@example.com" }


这将通过在电子邮件地址中增加一个数字来生成具有不同电子邮件地址的所有用户:[[email protected]](https://stackoverflow.com/cdn-cgi/l/email-protection)[[email protected]](https://stackoverflow.com/cdn-cgi/l/email-protection)[[email protected]](https://stackoverflow.com/cdn-cgi/l/email-protection).

sgtfey8w

sgtfey8w2#

在你的问题的最后,你把你得到的错误是
误差
第一个月
Factorybot将抛出此错误,如果你有两个工厂都命名为/是:用户
在整个应用中搜索factory :user
要么删除一个,要么重命名一个,因为我怀疑有两个。

相关问题