http://everydayrails.com/2012/03/19/testing-series-rspec-models-factory-girl.html# going off of this tutorial currently. i am adding on to another project that i started from the rails apps tutorial.
as i go to create my models specs contact_spec.rb
require 'spec_helper'
describe Contact do
it "has a valid factory" do
FactoryGirl.create(:contact).should be_valid
end
it "is invalid without a firstname"
it "is invalid without a lastname"
it "returns a contact's full name as a string"
end
factories/contacts.rb
require 'faker'
FactoryGirl.define do
factory :contact do |f|
f.firstname { Faker::Name.first_name }
f.lastname { Faker::Name.last_name }
end
end
i run rspec and recieve this error:
1) Contact has a valid factory
Failure/Error: FactoryGirl.create(:contact).should be_valid
NoMethodError:
undefined method `firstname=' for #<Contact name: nil, email: nil, content: nil>
# ./spec/models/contact_spec.rb:5:in `block (2 levels) in <top (required)>'
Finished in 0.22028 seconds
4 examples, 1 failure, 3 pending
here is my contact model
class Contact < ActiveRecord::Base
has_no_table
column :name, :string
column :email, :string
column :content, :string
validates_presence_of :name
validates_presence_of :email
validates_presence_of :content
validates_format_of :email, :with => /\A[-a-z0-9_+\.]+\@([-a-z0-9]+\.)+[a-z0-9]{2,4}\z/i
validates_length_of :content, :maximum => 500
def update_spreadsheet
connection = GoogleDrive.login(ENV["GMAIL_USERNAME"], ENV["GMAIL_PASSWORD"])
ss = connection.spreadsheet_by_title('Learn-Rails-Example')
if ss.nil?
ss = connection.create_spreadsheet('Learn-Rails-Example')
end
ws = ss.worksheets[0]
last_row = 1 + ws.num_rows
ws[last_row, 1] = Time.new
ws[last_row, 2] = self.name
ws[last_row, 3] = self.email
ws[last_row, 4] = self.content
ws.save
end
end
and my contactS_controller
class ContactsController < ApplicationController
def new
@contact = Contact.new
end
def create
@contact = Contact.new(secure_params[:contact])
if @contact.valid?
@contact.update_spreadsheet
UserMailer.contact_email(@contact).deliver
flash[:notice] = "Message sent from #{@contact.name}."
redirect_to root_path
else
render :new
end
end
private
def secure_params
params.require(:contact).permit(:name, :email, :content)
end
end
i tried changing :name to be :firstname, and :lastname and ended up getting this new error
1) Contact has a valid factory
Failure/Error: FactoryGirl.create(:contact).should be_valid
ActiveRecord::RecordInvalid:
Validation failed: Email can't be blank, Email is invalid, Content can't be blank
# ./spec/models/contact_spec.rb:5:in `block (2 levels) in <top (required)>'
Finished in 0.22596 seconds
4 examples, 1 failure, 3 pending
Failed examples:
rspec ./spec/models/contact_spec.rb:4 # Contact has a valid factory
my guess is that i havent defined something right when i reference to :contact.
edit adding the Faker::Internet.email attr brought up a new error
1) Contact has a valid factory
Failure/Error: FactoryGirl.create(:contact).should be_valid
ActiveRecord::RecordInvalid:
Validation failed: Content can't be blank
# ./spec/models/contact_spec.rb:5:in `block (2 levels) in <top (required)>'
so i comment out validates_presence_of :content, column :content, and validates_length_of :content and get this
1) Contact has a valid factory
Failure/Error: FactoryGirl.create(:contact).should be_valid
ActiveRecord::Tableless::NoDatabase:
Can't #create_record a Tableless object
# ./spec/models/contact_spec.rb:5:in `block (2 levels) in <top (required)>'
so it seems that things are working as i apply them or take away, i apparently have lots of conflicts between the code i wrote following one tutorial and adding this method using rspec factory_girl and faker
edit 2 so after the addition of the email and content attr, i continued on with filling out the remaining specs for "invalid without first/lastname":
describe Contact do
it "has a valid factory" do
FactoryGirl.build(:contact).should be_valid
end
it "is invalid without a firstname" do
FactoryGirl.build(:contact, lastname: nil).should_not be_valid
end
it "is invalid without a lastname" do
FactoryGirl.build(:contact, lastname: nil).should_not be_valid
end
it "returns a contact's full name as a string"
end
and my tests passed with no errors:
is invalid without a lastname
has a valid factory
is invalid without a firstname
returns a contact's full name as a string (PENDING: Not yet implemented)
Pending:
Contact returns a contact's full name as a string
# Not yet implemented
# ./spec/models/contact_spec.rb:15
Finished in 0.22146 seconds
4 examples, 0 failures, 1 pending
thank you sonnyhe2002 for getting me through this! much appreciated!
You need to add an email attr to your factory
FactoryGirl.define do
factory :contact do |f|
f.firstname { Faker::Name.first_name }
f.lastname { Faker::Name.last_name }
f.email { Faker::Internet.email }
f.content 'This is content'
end
end
Since you are using has_no_table, I think factory cannot save it into the database.
You should use 'build' instead of 'create'
FactoryGirl.build(:contact).should be_valid