undefined method 'password_confirmation' for User: Testing Authlogic with Cucumber and Factory Girl
My tests work fine when I'm testing them individually,
rake cucumber FEATURE = 'path/to/feature'
but when I try to run
rake cucumber
They fail with the following error
undefined method `password_confirmation=' for #<User:0x1069545f0> (NoMethodError)
This comes up when I try to create a user using Factory.build(:user). I have a factories file that defines a :user.
I don't really know how to confirm this, but its as though authlogic is not present and the User model does not have the added methods yet. When I look at the User methods (User.new.methods.include?("password_confirmation=")) at the time the Factory tries to build a new user, there is a method defined by that name.
I've done a lot of searching on this, and I don't see anything related, so I'm assuming that it's something else that I am doing.
EDIT:
A little more information - I've been able to reproduce this in a simple case:
------- .feature
Background:
Given user "Bad Admin" with email address "badmin@gmail.com" and password "password" exists with "admin" credentials
Given user "Good Admin" with email address "goodadmin@gmail.com" and password "password" exists with "edit" credentials
Scenario: valid log in with authorization
When I go to the login page
Scenario: invalid login
When I go to the login page
---- factories.rb
Factory.define :user do |u|
u.first_name "Arthur"
u.last_name "Dent"
u.email { Factory.next(:user_email) }
u.password "default"
u.password_confirmation "default"
end
---- steps.rb
Given /^user "([^"]*)" with email "([^"]*)", password "([^"]*)" and credentials "([^"]*)" exists$/ do |name, email, password, role|
names = name.split(' ')
user = Factory(:user, :first_name => names.first, :last_name => names.last, :email => email, 开发者_开发问答:password => password, :password_confirmation => password)
user.has_role! role.downcase.gsub(' ', '_')
end
Somewhere in your step definition file you should activate Authlogic with a before
step method:
Before do
include Authlogic::TestCase
activate_authlogic
end
Your user's factory should look like this one:
Factory.define :user do |f|
f.sequence(:id) { |n| n }
f.sequence(:username) { |n| "test#{n}" }
f.password "secret"
f.password_confirmation { |u| u.password }
f.sequence(:email) { |n| "test#{n}@example.com" }
end
But you don't need to use Factory for user creation. Here is my scenario for sign up and for existing user:
Scenario: Successful sign up
Given I am an anonymous user
And I am on the home page
When I follow "Join now!"
And I fill in "Username" with "test"
And I fill in "Email" with "test@mail.ru"
And I fill in "Password" with "secret"
And I fill in "Confirm Password" with "secret"
And I press "Create my account"
Then I should be logged in
Scenario Outline: Show Sign in or Sign out and Sign Up links
Given the following user records
| username | password |
| test | secret |
Given I am logged in as "<login>" with password "secret"
When I go to the home page
Then I should <action 1>
And I should <action 2>
Examples:
| login | action 1 | action 2 |
| test | see "Sign out" | see "My Profile" |
| | see "Sign in" | see "Sign up" |
Factory will be used in second scenario. Corresponding step's definitions:
Given /^I am an anonymous user$/ do
!UserSession.find
end
Then /^I should be logged in$/ do
UserSession.find
end
Given /^the following (.+) records$/ do |factory, table|
table.hashes.each do |hash|
Factory(factory, hash)
end
end
Given /^I am logged in as "([^\"]*)" with password "([^\"]*)"$/ do |username, password|
unless username.blank?
visit signin_url
fill_in "Username", :with => username
fill_in "Password", :with => password
click_button "Sign In"
end
end
精彩评论