使用Devise的confirmable模块进行测试(RSpec)

32

据我所知,Rails测试环境在每个测试之前都会被拆除和重建...那么,如何测试需要用户登录且该用户无法创建而又不受Device的confirmable模块干扰的控制器呢?

Devise的推荐方法(如下)创建一个新用户,然后由Devise的confirmable模块发送电子邮件。如何解决这个问题,使得我不必每次都“创建”用户……或者如果我确实要创建用户,如何获取一个可测试对象,而无需为每个规范“模拟”一封新邮件?

 before(:each) do
    @user = Factory.create(:user)
    sign_in @user
  end

我确定我正在忽略一些非常明显的东西,因为对于任何使用Devise和可确认性的人来说,这必须是一个非常普遍的规范...

8个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
35
在你的测试环境中,ActionMailer::Base.delivery_method 应该设置为 :test,这意味着这些电子邮件不会被发送出去。如果该设置被设置为其他东西,例如在 config/environments.rb 中进行配置的 smtp,则邮件将被发送出去。 如果该设置已经存在,那么要使用 User 对象(比如真正能够登录)需要在其上调用 confirm!
user = User.first
user.confirm!

1
ActionMailer::Base.delivery_method = :test 和自动生成的 config.action_mailer.delivery_method = :test 有什么不同吗? - Meltemi
1
好的,正在备份。电子邮件一开始没有发送出去,因为test.rb设置的原因。问题在于用户记录不是活动状态(或者Devise使用的任何术语),所以他们无法登录...每当在这些测试之前创建用户时,它就处于等待“确认”的临时状态,而测试失败... - Meltemi
4
@Meltemi:没错,这就是为什么在尝试对记录执行任何操作之前应该调用@user.confirm!。我会更新我的回答。 - Ryan Bigg
好的,接近成功了。@user.confirm! 是有帮助的,是朝着正确方向迈出的一步!但是,它仍然无法正常工作,因为我遇到了一个新的神秘错误:undefined method 'env' for nil:NilClass - Meltemi
这可能需要更新,在 devise-4.7.1 上似乎 @user.confirm 可以工作,但 @user.confirm! 未定义 NoMethodError: undefined method 'confirm!' for #<User:0x0000562eca83c2b0>。你是指 confirm 吗? - lacostenycoder
显示剩余2条评论

19

最新的FactoryGirl版本:

FactoryGirl.define do

  factory :confirmed_user, :parent => :user do
    after(:create) { |user| user.confirm }
  end

end

13

如果你正在使用 factory_girl 生成你的模型,你可以使用 after_create 来确认每一个新用户。

Factory.define :confirmed_user, :parent => :user do |f|
  f.after_create { |user| user.confirm! }
end

4
我相信,通过将confirmed_at Time.now添加为工厂属性,您将获得相同的效果。 - Giuseppe

10

Devise 4.2现在使用confirm而不是confirm!

来源

4.2.0 - 2016-07-01

删除了Devise :: Models :: Confirmable#confirm!方法,改用confirm。

以下代码还通过after(:build)而非after(:create)来设置confirmed_at,从而防止生成邮件。

FactoryGirl.define do
  factory :user do
    after(:build)   { |u| u.skip_confirmation_notification! }
    after(:create)  { |u| u.confirm }
    ...
  end
end

8

今天仅需放置:

确认于7天前

在您的制造中


2
尝试存根active?
@user = Factory.create(:user)
@user.stub(:active?).and_return(true)
sign_in @user
你可能还需要存根 confirmed?,我对Devise不太熟悉。

2

这个线程一段时间以来没有太多的活跃,但是对于现在有这个问题的人来说,你所需要做的就是创建一个被称为: confirmed的特性,它设置了必需的属性,当你使用它创建一个用户时,你将能够登录而不需要多次保存用户数据库记录。

  # Use faker library (installed separately) to set realistic seed data
  require 'faker'

  # Factory definition
  factory :user, do
    email { Faker::Internet.unique.email }
    password { Faker::Internet.password(min_length: 12, max_length: 128) }

    trait :confirmed do
      confirmed_at { Time.zone.now }
      confirmation_sent_at { Time.zone.now }
      confirmation_token { '12345' }
    end
  end

  # Example of using it
  user = create(:user, :confirmed)

1

对于制作宝石,它是这样的

Fabricator(:user) do
  after_build { |user| user.confirm! }
end

2
需要使用 after_create,而不是 after_build 吗? - slothbear

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,