FactoryGirl.attributes_for(:item) not passing on POST #create - ruby-on-rails

I try to pass these two create controller specs but for some reason it it not validating the Item object. Could it be that FactoryGirl.attributes_for(:item) are missing the profile and attachment required associations? If so, how can I pass it to attributes too?
describe "POST #create" do
context "signed in" do
login_user
context "with valid attributes" do
it "creates a new item" do
expect{
post :create, trend: FactoryGirl.attributes_for(:item)
}.to change(Item,:count).by(1)
end
it "redirects to the home page" do
post :create, item: FactoryGirl.attributes_for(:item)
response.should redirect_to Item.last
end
end
end
I got these errors
Failures:
1) ItemsController POST #create signed in with valid attributes creates a new item
Failure/Error: expect{
count should have been changed by 1, but was changed by 0
# ./spec/controllers/items_controller_spec.rb:42:in `block (5 levels) in <top (required)>'
2) ItemsController POST #create signed in with valid attributes redirects to the home page
Failure/Error: response.should redirect_to Item.last
Expected response to be a <redirect>, but was <200>
# ./spec/controllers/items_controller_spec.rb:48:in `block (5 levels) in <top (required)>'
This is the Item factory
FactoryGirl.define do
factory :item do
profile
after(:build) do |item|
item.attachments << FactoryGirl.build(:attachment, attachable: item)
end
end
end

I guess doing FactoryGirl.attributes_for isn't actually a build, so the after(:build) won't fire. How about this:
FactoryGirl.attributes_for(:item, :profile_attributes => FactoryGirl.attributes_for(:profile), :attachments => [FactoryGirl.attributes_for(:subject)])
Probably a good idea to try this line in the rails console first to see what the hash comes out like :)

Related

Failing uniqueness validation with FactoryGirl

I'm having problems with FactoryGirl, I'm using sequence to avoid duplicating fields, but validations are failing anyway.
Output:
1) CustomersController anonymous user GET #edit is redirected to signin when accessing edit form
Failure/Error: get :edit, id: create(:customer)
ActiveRecord::RecordInvalid:
Validation failed: Email has already been taken, Email has already been taken
# ./spec/controllers/customers_controller_spec.rb:25:in `block (4 levels) in <top (required)>'
# -e:1:in `<main>'
3) Customer public class methods executes its methods correctly #find_by_id_or_name finds customer by name
Failure/Error: let(:john) {create(:customer, name: 'John Doe X')}
ActiveRecord::RecordInvalid:
Validation failed: Email has already been taken, Email has already been taken
# ./spec/models/customer_spec.rb:25:in `block (3 levels) in <top (required)>'
# ./spec/models/customer_spec.rb:38:in `block (5 levels) in <top (required)>'
# -e:1:in `<main>'
Factories:
FactoryGirl.define do
factory :customer do
user
name {Faker::Name.name}
sequence(:mail) { |n| "person#{n}#example.com" }
address {Faker::Address.street_address}
phone {Faker::PhoneNumber.phone_number}
end
end
FactoryGirl.define do
factory :user do
sequence(:email) {|i| "example#{i}#example.com"}
password {Faker::Internet.password(10)}
end
end
These are the tests that are failing:
RSpec.describe Customer, type: :model do
describe "public class methods" do
let(:john) {create(:customer, name: 'John Doe X')}
let(:frank) {create(:customer)}
context "responds to its methods" do
it "responds to #find_by_id_or_name" do
expect(Customer).to respond_to(:find_by_id_or_name)
end
end
context "executes its methods correctly" do
context "#find_by_id_or_name" do
it "finds customer by name" do
customer = Customer.find_by_id_or_name('John Doe X')
expect(customer).to eq john
end
it "finds customer by id" do
customer = Customer.find_by_id_or_name(frank.id)
expect(customer).to eq frank
end
end
end
end
end
RSpec.describe CustomersController, type: :controller do
context "signed in user" do
before :each do
#user = create(:user)
end
describe "GET #edit" do
it "renders :edit view" do
get :edit, id: create(:customer).id
expect(response).to render_template(:edit)
end
end
describe "DELETE #destroy" do
before :each do
#customer = create(:customer, user: #user)
end
it "deletes record" do
expect {delete :destroy, id: #customer.id}.to change(Customer, :count).by(-1)
end
end
end
end
This is happening to me all over my app. I just copied some tests that apply to Customer.
Thanks
My problem was related to not appropiately configuring database_cleaner. The configuration in this post solves the problem: How can I clean my database between erroneous rspec specs?

Post request in controller specs

I have problem with testing my controller. I've test post request in 2 context. With valid attributes and with invalid attributes. I have problem with valid attributes context.
I have the following test:
describe "POST #create" do
context "with valid attributes" do
it "saves the new car_configuration in the database" do
expect{
post :create, car_configuration: attributes_for(:car_configuration)
}.to change(CarConfiguration, :count).by(1)
end
it "redirects to the index car_configuration" do
post :create, car_configuration: attributes_for(:car_configuration)
should redirect_to admin_car_configurations_url
end
end
end
And my car_configuration factory is:
FactoryGirl.define do
factory :car_configuration do
sequence(:image) {|n| "Image #{n}"}
small_cases_count 5
big_cases_count 2
association :body_style, factory: :car_body_style
association :model, factory: :car_model
association :car_class
end
end
And errors that rspec shows:
1) Admin::CarConfigurationsController POST #create with valid attributes saves the new car_configuration in the database
Failure/Error: expect{
count should have been changed by 1, but was changed by 0
# ./spec/controllers/admin/car_configurations_controller_spec.rb:42:in `block (4 levels) in <top (required)>'
2) Admin::CarConfigurationsController POST #create with valid attributes redirects to the index car_configuration
Failure/Error: should redirect_to admin_car_configurations_url
Expected response to be a <redirect>, but was <200>
# ./spec/controllers/admin/car_configurations_controller_spec.rb:49:in `block (4 levels) in <top (required)>'
spec/controllers/admin/car_configuratoins_controller_spec.rb
require 'spec_helper'
describe Admin::CarConfigurationsController do
let(:configuration) { build :configuration }
context "POST create" do
it "creates a config" do
expect { perform }.to change(CarConfiguration, :count).by(1)
end
def perform
post :create, car_configuration: configuration.attributes
end
end
end

FactoryGirl::InvalidFactoryError Controller Spec

I'm trying to create a controller spec for a contact form. All I want is to test that the :new template is rendered when invalid attributes are submitted. I've tried various configurations of the factory, as well as changing it to a trait, instead of factory to no avail. The error message doesn't get very specific, just Invalid Factory. Any ideas would be appreciated!
# blog_app/spec/factories/inquiries.rb
FactoryGirl.define do
factory :inquiry do
name "TestName"
email "test#test.com"
phone "123-456-7890"
message "TestMessage"
end
factory :invalid_inquiry, parent: :inquiry do
name nil
end
end
#/app/controllers/inquiries_controller.rb
class InquiriesController < ApplicationController
def new
#inquiry = Inquiry.new
end
def create
#inquiry = Inquiry.new(params[:inquiry])
if #inquiry.deliver
render :thank_you
else
render :new
end
end
end
# spec/controllers/inquiries_controller_spec.rb
require 'spec_helper'
describe InquiriesController do
it "has a valid factory" do
FactoryGirl.build(:inquiry).should be_valid
end
describe "POST #create" do
context "with valid attributes" do
it "delivers inquiry" #pending
it "renders the :thank_you page template" do
post :create, inquiry: FactoryGirl.attributes_for(:inquiry)
response.should render_template :thank_you
end
end
context "with invalid attributes" do
it "does not deliver inquiry" do #pending
it "renders :new page template" do
post :create, inquiry: FactoryGirl.attributes_for(:invalid_inquiry)
response.should render_template :new
end
end
end
describe "GET #new" do
it "renders :new page template" do
get :new
response.should render_template :new
end
end
end
Finished in 0.31244 seconds
0 examples, 0 failures
/Users/.../.rvm/gems/ruby-2.0.0-p353/gems/factory_girl-4.4.0/lib/factory_girl.rb:73:in `lint': The following factories are invalid: (FactoryGirl::InvalidFactoryError)
* invalid_inquiry
from /Users/.../Documents/blog_app/spec/support/factory_girl.rb:8:in `block (2 levels) in <top (required)>'
from /Users/.../.rvm/gems/ruby-2.0.0-p353/gems/rspec-core-2.13.1/lib/rspec/core/hooks.rb:21:in `instance_eval'
from /Users/.../.rvm/gems/ruby-2.0.0-p353/gems/rspec-core-2.13.1/lib/rspec/core/hooks.rb:21:in `run'
from /Users/.../.rvm/gems/ruby-2.0.0-p353/gems/rspec-core-2.13.1/lib/rspec/core/hooks.rb:66:in `block in run'
from /Users/.../.rvm/gems/ruby-2.0.0-p353/gems/rspec-core-2.13.1/lib/rspec/core/hooks.rb:66:in `each'
from /Users/.../.rvm/gems/ruby-2.0.0-p353/gems/rspec-core-2.13.1/lib/rspec/core/hooks.rb:66:in `run'
from /Users/.../.rvm/gems/ruby-2.0.0-p353/gems/rspec-core-2.13.1/lib/rspec/core/hooks.rb:418:in `run_hook'
from /Users/.../.rvm/gems/ruby-2.0.0-p353/gems/rspec-core-2.13.1/lib/rspec/core/command_line.rb:27:in `block in run'
from /Users/.../.rvm/gems/ruby-2.0.0-p353/gems/rspec-core-2.13.1/lib/rspec/core/reporter.rb:34:in `report'
from /Users/.../.rvm/gems/ruby-2.0.0-p353/gems/rspec-core-2.13.1/lib/rspec/core/command_line.rb:25:in `run'
from /Users/.../.rvm/gems/ruby-2.0.0-p353/gems/rspec-core-2.13.1/lib/rspec/core/runner.rb:80:in `run'
from /Users/.../.rvm/gems/ruby-2.0.0-p353/gems/rspec-core-2.13.1/lib/rspec/core/runner.rb:17:in `block in autorun'
Does this work?
FactoryGirl.define do
factory :inquiry do
name "TestName"
email "test#test.com"
phone "123-456-7890"
message "TestMessage"
factory :invalid_inquiry do
name nil
end
end
end
Alternatively you might try replacing:
post :create, inquiry: FactoryGirl.attributes_for(:invalid_inquiry)
with:
post :create, inquiry: FactoryGirl.attributes_for(:inquiry, name: nil)
and getting rid of the invalid_inquiry factory altogether.

ActiveRecord reporting a failed validation, but there are no validations defined

I'm just starting to use RSpec with a new project (after being a minitest user for a while). I've created a single MVC, called contracts. Here is the model file:
class Contract < ActiveRecord::Base
attr_accessible :name, :number, :plannedStart, :actualStart, :plannedCompletion, :actualCompletion
end
I've got a basic factory defined for Contracts (it was slightly more complex earlier, using sequence to generate novel names and numbers, but I removed all of that to try to simplify squashing this bug):
FactoryGirl.define do
factory :contract do
end
end
Here are the specs (pretty much auto generated, except I added in the calls to the factory):
require File.dirname(__FILE__) + '/../spec_helper'
describe ContractsController do
render_views
it "index action should render index template" do
create(:contract)
get :index
response.should render_template(:index)
end
it "show action should render show template" do
create(:contract)
get :show, :id => Contract.first
response.should render_template(:show)
end
it "new action should render new template" do
get :new
response.should render_template(:new)
end
it "create action should render new template when model is invalid" do
Contract.any_instance.stubs(:valid?).returns(false)
post :create
response.should render_template(:new)
end
it "create action should redirect when model is valid" do
Contract.any_instance.stubs(:valid?).returns(true)
post :create
response.should redirect_to(contract_url(assigns[:contract]))
end
it "edit action should render edit template" do
create(:contract)
get :edit, :id => Contract.first
response.should render_template(:edit)
end
it "update action should render edit template when model is invalid" do
create(:contract)
Contract.any_instance.stubs(:valid?).returns(false)
put :update, :id => Contract.first
response.should render_template(:edit)
end
it "update action should redirect when model is valid" do
create(:contract)
create(:contract)
Contract.any_instance.stubs(:valid?).returns(true)
put :update, :id => Contract.first
response.should redirect_to(contract_url(assigns[:contract]))
end
it "destroy action should destroy model and redirect to index action" do
create(:contract)
contract = Contract.first
delete :destroy, :id => contract
response.should redirect_to(contracts_url)
Contract.exists?(contract.id).should be_false
end
end
When I run the spec, I get the following error message, but the number of these I get varies from run to run:
ActiveRecord::RecordInvalid: Validation failed:
./spec/controllers/contracts_controller_spec.rb:39:in `block (2 levels) in <top (required)>'
ActiveRecord::RecordInvalid: Validation failed:
./spec/controllers/contracts_controller_spec.rb:45:in `block (2 levels) in <top (required)>'
ActiveRecord::RecordInvalid: Validation failed:
./spec/controllers/contracts_controller_spec.rb:7:in `block (2 levels) in <top (required)>'
10 examples, 3 failures, 7 passed
Finished in 0.360139 seconds
/Users/jlee/.rvm/rubies/ruby-1.9.3-p194/bin/ruby -S rspec ./spec/controllers/contracts_controller_spec.rb ./spec/models/contract_spec.rb failed
I've implemented Databasecleaner just to make sure this wasn't some odd behavior problem relating to using transactions during testing, but to no avail. Suggestions? I have no validations defined, so its hard to understand how I could be failing validation.
The stub for :valid? hangs around between tests, so I put the following in the before(:each) block: Contract.any_instance.unstub(:valid?), and it cleared everything up.

post create test for user count failing. Should be changed by 1, but was changed by 0

Been trying to figure this out for a while now, but can't seem to go green. Here is the rspec error that I am getting:
1) UsersController POST create with valid parameters creates a new user
Failure/Error: expect {post :create, user}.to change(User, :count).by 1
count should have been changed by 1, but was changed by 0
# ./spec/controllers/users_controllers_spec.rb:36:in `block (4 levels) in <top
(required)>'
Here is my relevant test in the users_controllers_spec:
describe UsersController do
let(:user) {FactoryGirl.create :user}
context 'POST create' do
context 'with valid parameters' do
before {post :create, user}
let(:user) {FactoryGirl.build :user}
it 'creates a new user' do
expect {post :create, user}.to change(User, :count).by 1
end
it {should respond_with 200}
end
And here is my users_controller create method:
def create
#user = User.new(params[:user])
if #user.save
sign_in #user
flash[:success] = "Welcome #{#user.name.capitalize}! Please complete your profile."
redirect_to profile_path(current_user)
else
render :new
end
end
Also, here is my factories.rb file:
FactoryGirl.define do
factory :user do
name "John"
email "John#example.com"
password "password"
password_confirmation "password"
end
end
What am I missing? I feel like it is something really obvious, but I can't seem to figure it out. Any help would be much appreciated.
Your test involves creating a second user with FactoryGirl, but the creation of the second user is failing because the email is the same as the first and you have a uniqueness validation on that attribute.
You can either not create the first user at all or you'll need to make the emails different (e.g. by passing in an email parameter to your FactoryGirl call or changing the Factory to make each email address unique).

Resources