【发布时间】:2018-03-15 17:49:43
【问题描述】:
我在使用 rspec 在 Rails 中进行测试时遇到问题。总而言之,我有 4 个模型之间的结构,但目前我尝试解决其中两个模型的测试。我正在使用 faker 和 FactoryGirl 并拥有以下工厂:
require 'faker'
FactoryGirl.define do
factory :user do |f|
f.name { Faker::Name}
f.email { Faker::Internet.email}
f.password {Faker::Internet.password}
f.role {"Kindergarten"}
end
end
require 'faker'
FactoryGirl.define do
factory :child do |f|
f.name { Faker::Name}
f.city { Faker::Address.city}
f.postalcode {Faker::Number.between(30000,35000)}
f.streed {Faker::Address.street_name}
f.add_number {Faker::Address.secondary_address}
f.disability { Faker::Boolean.boolean}
f.halal { Faker::Boolean.boolean}
f.koscha {Faker::Boolean.boolean}
f.vegetarian {Faker::Boolean.boolean}
f.vegan {Faker::Boolean.boolean}
f.allday { Faker::Boolean.boolean}
f.gender { Faker::Number.between(0,1)}
f.user_id {Faker::Number.between(1,10)}
end
end
我的控制器测试看起来像这样
require 'rails_helper'
require 'factory_girl_rails'
describe UsersController do
before do
3.times { FactoryGirl.create(:child)}
end
describe "GET #show" do
let(:user) { FactoryGirl.create(:user) }
before { get :show, id: user.id}
it "assigns the requested user to @user" do
assigns(:user).should eq user
end
it "renders the :show template"
end
describe "GET #new" do
let(:user) { FactoryGirl.create(:user) }
it "assigns a new User to @user" do
get :new, id: user.id
assigns(:user).should be_a_new(User)
end
it "renders the :new template"
end
end
当我尝试运行测试时,我收到此错误消息
UsersController GET #new assigns a new User to @user
Failure/Error: 3.times { FactoryGirl.create(:child)}
ActiveRecord::RecordInvalid:
Validation failed: User can't be blank
我在模型中的关系和验证如下
class Child < ApplicationRecord
has_many :relations, :dependent => :destroy
accepts_nested_attributes_for :relations
belongs_to :user
validates :user, presence: true
validates :name, presence: true, length: { maximum: 50 }
validates :city, presence: true, :on => :create
validates :postalcode, presence: true, numericality: true
validates :streed, presence: true
validates :add_number, presence: true
validates :disability, inclusion: { in: [true, false] }
validates :halal, inclusion: { in: [true, false] }
validates :koscha, inclusion: { in: [true, false] }
validates :vegetarian, inclusion: { in: [true, false] }
validates :vegan, inclusion: { in: [true, false] }
validates :allday, inclusion: { in: [true, false] }
validates :gender, presence: true
end
class User < ApplicationRecord
attr_accessor :remember_token, :activation_token, :reset_token
has_many :children, dependent: :destroy
has_many :kindergartens, dependent: :destroy
has_many :relations, dependent: :destroy
before_save :downcase_email
before_create :create_activation_digest
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
validates :role, presence: true
has_secure_password
validates :password, presence: true, length: { minimum: 6 }, allow_nil: true
end
我的问题是,我不确定我的 rspec 代码是否存在错误,或者我的正常模型中的验证和关系是否存在错误。有人可以帮我吗?
【问题讨论】:
-
在子工厂中,
f.user_id应该引用现有的用户记录。目前不是,这会在创建子项时引发此空白错误。使用f.assocation(:user, :factory => :user)而不是f.user_id行。如果您的测试套件不需要Child对象具有关联的User记录,则可以仅针对此测试上下文模拟Child的user方法,从而节省一些性能 -
顺便说一句,
FactoryGirl.create_list(:factory_name, 3)比3.times { create(:factory_name) }更有效 -
@MrYoshiji 你应该把这个留作 ann annswer
-
感谢您的帮助。我已经像你说的那样尝试了替换 f.user_id 行,但是我得到了一个新错误,参数数量错误 Failure/Error: f.assocation(:user, : factory => :user) {Faker::Number.between(1,10)} ArgumentError:参数数量错误(给定 3,预期 1..2)
-
你可以直接说
association :user,甚至可以直接说user
标签: ruby-on-rails ruby rspec-rails faker