kuwantum
kuwantum

Reputation: 314

Testing a signup confirmation with Rspec/Factory Girl/Rails

Trying to create an Rspec/Factory girl test to make sure that Devise's confirmation on signup is covered - the site has 3 languages (Japanese, English, Chinese) so I want to make sure nothing breaks the signup process.

I have the following factories: user.rb << Has everything needed for the general user mailer tests signup.rb which has:

FactoryGirl.define do
  factory :signup do
    token "fwoefurklj102939"
    email "[email protected]"
  end
end

The devise user_mailer method that I want to test is:

def confirmation_instructions(user, token, opts={})
  @user = user
  set_language_user_only
  mail to: @user.email,
       charset: (@user.language == User::LANGUAGE_JA ? 'ISO-2022-JP' : 'UTF8')
end

I cannot for the life of me figure out how to get the token part to work in the test - any advice or ideas?

I have been trying something along these lines (to check the email is being sent) without success:

describe UserMailer, type: :mailer do

  describe "sending an email" do
    after(:all) { ActionMailer::Base.deliveries.clear }

    context "Japanese user emails" do
      subject(:signup) { create(:signup) }
      subject(:user) { create(:user) }

      subject(:mail) do
        UserMailer.confirmation_instructions(user, token, opts={})
      end

      it "sends an email successfully" do
        expect { mail.deliver }.to change { ActionMailer::Base.deliveries.size }.by(1)
      end
    end
  end
end

The resulting error is undefined local variable or methodtoken'and I cannot work out why it is not coming from thesignup` factory. I tried changing

subject(:mail) do
  UserMailer.confirmation_instructions(user, token, opts={})
end

to

subject(:mail) do
  UserMailer.confirmation_instructions(user, signup.token, opts={})
end

but then I received this error:

Failure/Error: subject(:signup) { create(:signup) }

     NameError:
       uninitialized constant Signup

EDIT: I forgot to mention something important - the actual code all works for user signups in all 3 languages, so I am certain that this is definitely my inexperience with testing at fault.

Upvotes: 0

Views: 511

Answers (1)

max
max

Reputation: 101811

subject(:mail) do
  UserMailer.confirmation_instructions(user, user.confirmation_token)
end

This varies of course depending on what your exact implementation is but your user class should be generating the token:

require 'secure_random'

class User
  before_create :generate_confirmation_token!

  def generate_confirmation_token!
    confirmation_token = SecureRandom.urlsafe_base64
  end
end

Creating a separate factory is unnecessary and won't work since FactoryGirl will try to create an instance of Signup which I'm guessing that you don't have.

Factories are not fixtures.

Upvotes: 1

Related Questions