【问题标题】:Factory Girl Devise user factory is not valid - doesn't pass RSpec testFactory Girl Devise 用户工厂无效 - 未通过 RSpec 测试
【发布时间】:2015-01-27 22:47:31
【问题描述】:

我是编程新手,已经学习 Ruby on Rails 大约 11 周了。

当尝试测试我的用户工厂进行验证时,我得到了

  1) User has a valid factory
     Failure/Error: expect(@user.valid?).to eq(true)

       expected: true
            got: false

       (compared using ==)

我将 Devise 用于我的用户模型,并将 FactoryGirl 用于我的工厂。

这是我的用户工厂:

FactoryGirl.define do 
  factory :user do
    name "John Fahey"
    sequence(:email, 100) { |n| "person#{n}@example.com" }
    password "password"
    password_confirmation "password"
    confirmed_at Time.now
  end
end

...这是我的规格

require 'rails_helper'

  describe User do 
    before do
      @user = build(:user)
    end

  it "has a valid factory" do
   expect(@user.valid?).to eq(true)
   end 
end

我一直在努力让这个规范通过一段时间。有一段时间我收到“电子邮件已被接收”的错误,我已经过去了。我什至让规范通过了一次,但我使用的是现在已弃用的“应该是”语法。当我使用正确的 ":expect" 语法时,我得到了这个错误。有谁知道我在这里做错了什么?

这是我的模型

class User < ActiveRecord::Base

  #== schema information. 
  # create_table "users", force: true do |t|
  #   t.string   "name"
  #   t.string   "email",                  default: "", null: false
  #   t.string   "encrypted_password",     default: "", null: false
  #   t.string   "reset_password_token"
  #   t.datetime "reset_password_sent_at"
  #   t.datetime "remember_created_at"
  #   t.integer  "sign_in_count",          default: 0,  null: false
  #   t.datetime "current_sign_in_at"
  #   t.datetime "last_sign_in_at"
  #   t.string   "current_sign_in_ip"
  #   t.string   "last_sign_in_ip"
  #   t.string   "confirmation_token"
  #   t.datetime "confirmed_at"
  #   t.datetime "confirmation_sent_at"
  #   t.string   "unconfirmed_email"
  #   t.datetime "created_at"
  #   t.datetime "updated_at"
  # end

  # add_index "users", ["email"], name: "index_users_on_email", unique: true
  # add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true


  has_one :list
  has_many :items, through: :list
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable, :confirmable
end

这是我在 Rails 控制台中创建用户实例并测试错误时看到的内容:

2.0.0-p576 :004 > @user = User.create
   (0.2ms)  begin transaction
   (0.2ms)  rollback transaction
 => #<User id: nil, name: nil, email: "", encrypted_password: "", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_coun
t: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, confirmation_token: nil, confirmed_at: nil, confirmation_sen
t_at: nil, unconfirmed_email: nil, created_at: nil, updated_at: nil>
2.0.0-p576 :005 > @user.save
   (1.0ms)  begin transaction
   (0.1ms)  rollback transaction
 => false
2.0.0-p576 :006 > puts(@user.errors)
#<ActiveModel::Errors:0xa7cff88>
 => nil
2.0.0-p576 :007 >

当我打印错误消息时,我得到

2.0.0-p576 :007 > puts(@user.errors.messages)
{:email=>["can't be blank"], :password=>["can't be blank"]}
 => nil

这里有一些有趣的东西。为了确保,我做了一个 rake db:migrate 和一个 rake db:test:prepare。测试通过了。然后我再次进行了精确的测试,它失败了。

vagrant@rails-dev-box:~/code/blocitoff$ rake db:migrate
vagrant@rails-dev-box:~/code/blocitoff$ rake db:migrate
vagrant@rails-dev-box:~/code/blocitoff$ rake db:test:prepare
vagrant@rails-dev-box:~/code/blocitoff$ rspec spec/models/user_spec.rb
#<ActiveModel::Errors:0xbdf0740>
.

Finished in 0.1764 seconds (files took 8.96 seconds to load)
1 example, 0 failures
vagrant@rails-dev-box:~/code/blocitoff$ rspec spec/models/user_spec.rb
#<ActiveModel::Errors:0xa97066c>
F

Failures:

  1) User has a valid factory
     Failure/Error: expect(@user.valid?).to eq(true)

       expected: true
            got: false

       (compared using ==)

【问题讨论】:

  • 请张贴app/models/user.rb 并进行验证。
  • 没有看到你的模型很难说。调试为什么它在“有一个有效的工厂”内抱怨,例如with:@user.errors 在断言之前。
  • 好的,我已经更新了我的问题以包含我的模型和架​​构信息。
  • @EricLowber 尝试像@blelump 一样进行调试,输入@user.save;puts(@user.errors) 并查看log/test.log 是否有任何发生。设计有自己的验证,看起来其中一些未通过您的测试。
  • 好的。当我尝试调试和创建用户实例时,该实例甚至没有 user_id。 Rails 不应该自动生成吗?

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


【解决方案1】:

您的 email 属性必须是唯一的,并且您没有在测试之间清理数据库,因此您在第二次和后续执行测试时出错。请参阅https://relishapp.com/rspec/rspec-rails/docs/transactions 了解 RSpec 中事务的使用。

【讨论】:

  • 好吧,问题是,我确实有一个数据库清理器。但是,我的数据库清理文件中有错误的语法。没有大写 DatabaseCleaner。相反,有 databaseCleaner。
  • 我很好奇:您是否使用 databaseCleaner 引用生成了可见错误?
  • 没有。我正准备说我已经有了一个数据库清理器。然后我检查了文件以确保一切都井井有条 - 并发现它不是。顺便说一句,谢谢你的帮助。
【解决方案2】:

只是为了包装彼得所说的,我能够通过将此设置添加到我的 spec_helper.rb 来解决我的问题。

RSpec.configure do |config|
  config.use_transactional_fixtures = true
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-27
    • 2012-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多