16

Using rails, devise, rspec & factorygirl:

Trying to create some tests for my site. I'm using the confirmable model for devise so when I create a user using FactoryGirl, the user isn't confirmed.

This is my factories.rb:

FactoryGirl.define do
  factory :user do
    full_name             "Aren Admin"
    email                 "aren@example.com"
    password              "arenaren"
    password_confirmation "arenaren"
    role_id               ADMIN
  end
end

And this is my rspec test file:

require 'spec_helper'

describe "Admin pages" do

  subject { page }

  describe "home page" do
    let(:user) { FactoryGirl.create(:user) }
    before { visit admin_home_path }

    it { should have_content("#{ROLE_TYPES[user.role_id]}") }
  end
end

I'm getting an error because the user is not confirmed. By searching around I'm pretty sure I need to use the method 'confirm!' and that it belongs in the factories.rb file, but I'm not sure where to put it.

Kevin K
  • 2,191
  • 2
  • 28
  • 41

8 Answers8

35

You could also set the confirmed_at attribute as follows. Works for me:

FactoryGirl.define do
  factory :user do
    full_name             "Aren Admin"
    email                 "aren@example.com"
    password              "arenaren"
    password_confirmation "arenaren"
    role_id               ADMIN
    confirmed_at          Time.now
  end
end
auralbee
  • 8,741
  • 4
  • 29
  • 36
  • I have been preferring this method over `confirm!` because it is one less operation. – IAmNaN Aug 27 '13 at 21:23
  • replaced two lines with one...and a little more intuitive, imo. Thanks! – brntsllvn Jun 14 '15 at 01:20
  • This is the cleanest way to do it. Thanks :+1: – moeabdol Feb 17 '16 at 13:26
  • 2
    Note that `Time.now` would be executed when the factory is defined, not when the user object is created. It's recommended to pass a block like `confirmed_at { Time.now }` to set `confirmed_at` when it's created. – Petr Bela Feb 10 '17 at 11:24
24

Better yet, do the following (then you don't need to create a before filter for every test suite)

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

found here: https://stackoverflow.com/a/4770075/1153149

Edit to add non-deprecated syntax

FactoryGirl.define do |f|
  #Other factory definitions

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

Edit 01/27 To Update Syntax Again

FactoryGirl.define do
  #Other factory definitions

  factory :confirmed_user, :parent => :user do
    after(:create) { |user| user.confirm! }
  end
end
Community
  • 1
  • 1
Joeyjoejoejr
  • 904
  • 5
  • 11
  • 1
    hi! I have used your method and it says > undefined method after_create. why is that? – oFca Oct 09 '12 at 21:12
  • I need more information, what object is it trying to run after_create on? It might be that this is pulled from an old answer. I think the Factory.define syntax might be depricated. I'll edit my answer with the up-to-date syntax. Let me know if that doesn't work. – Joeyjoejoejr Oct 11 '12 at 18:12
  • This is a good answer and what I usually use... except ThoughtBot changed the syntax again (are we there yet?). It should be `after(:create) {...etc` – IAmNaN Aug 27 '13 at 21:20
9

Try user.confirm! in your before block

found here

caulfield
  • 1,383
  • 1
  • 11
  • 21
3

This is the factory that worked for me

FactoryGirl.define do
  factory :user do
    sequence :email do |n|
      "address#{n}@example.com"
    end
    sequence :password do |n|
      "password#{n}"
    end

    factory :confirmed_user do
      before(:create) {|user| user.skip_confirmation! }
    end
  end
end
stujo
  • 2,089
  • 24
  • 29
2

Add this line to your User factory definition:

before(:create) { |user| user.skip_confirmation! }
taylorthurlow
  • 2,953
  • 3
  • 28
  • 42
Naveen LP
  • 61
  • 2
2

Put the Devise confirmable logic in the after(:build) callback...

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

For me, putting confirm! or skip_confirmation! in the after(:create) block caused validation errors on the email parameter and did not work.

vanboom
  • 1,274
  • 12
  • 20
1

You should call skip_confirmation! before create so this is persisted on the user.

before(:create) do |user|
  user.skip_confirmation!
end
Jeremy Lynch
  • 6,780
  • 3
  • 52
  • 63
0

2023

Does not work:

before(:create, &:skip_confirmation!)

Works:

after(:build, &:skip_confirmation!)
Petercopter
  • 1,218
  • 11
  • 16