Object.save failed in spec data validation

折月煮酒 提交于 2019-12-12 02:46:15

问题


Here is the failed spec code for create in customer controller:

describe CustomersController do

  before(:each) do
    #the following recognizes that there is a before filter without execution of it.
    controller.should_receive(:require_signin)
    controller.should_receive(:require_employee)
  end

  render_views

    describe "'create' successful" do
      before(:each) do
        category = Factory(:category)
        sales = Factory(:user)      
        @customer = Factory.attributes_for(:customer, :category1_id => category.id, :sales_id => sales.id)
        session[:sales] =  true
        session[:user_id] = sales.id
        session[:user_name] = sales.name
        session[:page_step] = 1
        session['page1'] = customers_path
      end

      it "should create one customer record" do
        lambda do
          post 'create', @customer         
        end.should change(Customer, :count).by(1)
      end

      it "should redirect to customers path" do
        put 'create', @customer
        flash[:notice].should_not be_nil
        response.should redirect_to(customers_path)
      end
    end
 end

The customer has both sales id and category id which belong to user and category table respectively.

Here is the spec failure error:

  1) CustomersController GET customer page 'create' successful should create one customer record
     Failure/Error: lambda do
       count should have been changed by 1, but was changed by 0
     # ./spec/controllers/customers_controller_spec.rb:37:in `block (4 levels) in <top (required)>'

  2) CustomersController GET customer page 'create' successful should redirect to customers path
     Failure/Error: flash[:notice].should_not be_nil
       expected: not nil
            got: nil
     # ./spec/controllers/customers_controller_spec.rb:44:in `block (4 levels) in <top (required)>'

Here is the app code for create in customer controller:

  def create

    if session[:sales]
      @customer = Customer.new(params[:customer], :as => :roles_new_update)
      @customer.sales_id = session[:user_id]
      if @customer.save 
        @message = "New customer #{params[:name]} was created. Please check it out"
        @subject = "New customer #{params[:name]} was created BY {#session[:user_name]}"
        UserMailer.notify_tl_dh_ch_ceo(@message, @subject, session[:user_id])
        redirect_to session[('page' + session[:page_step].to_s).to_sym], :notice => 'Customer was created successfaully!'          
      else
        render 'new', :notice => 'Customer was not saved!'
      end
    end
  end

Here is the code in factories.rb:

Factory.define :customer do |c|
  c.name                    "test customer"
  c.short_name              "test"   
  c.email                   "t@acom.com"
  c.phone                   "12345678"
  c.cell                    "1234567890"
  c.active                  1
  c.category1_id            2
  c.sales_id                1
  c.address                 "1276 S. Highland Ave, Lombard, IL 67034"
  c.contact                 "Jun C"

end

Factory.define :category do |c|
  c.name                   "category name"
  c.description            "test category"
  c.active                 true
end

Factory.define :user do |user|

  user.name                  "Test User"
  user.email                 "test@test.com"
  user.password              "password1"
  user.password_confirmation "password1"
  user.status                "active"
  user.user_type             "employee"

end

It seems that the error was caused by @customer.save returning false and the code for "if @customer.save" was not executed. So the problem may be with the @customer generated by Factory which seems good to me. The code is executed without any problem when saving a customer.

Any suggestions? Thanks.


回答1:


I would break this up into two specific tests. Right now you're unsure of two things:

  1. is the customer is being told to save itself?
  2. Is there a validation that is preventing customer from being saved?

The quickest path is to change @customer.save to @customer.save! and see if there are any exceptions raised (it will do so if a validation failed).

I recommend you split this up though. To test #1, in the controller spec:

it "should tell the customer to save itself when there is a session[:sales]" do
  session[:sales] = true
  customer_mock = double(:customer)
  customer_mock.should_receive(:sales_id=)
  customer_mock.should_receive(:save).and_return(:true)
  Customer.stub(:new => cutomer_mock)
  post 'create'
end

Then in your customer_spec, test out:

it "should be valid with factory specs" do
  customer = Customer.new(Factory.attributes_for(:customer))
  customer.should be_valid
end



回答2:


post :create, :customer => @customer

solves the problem with above.



来源:https://stackoverflow.com/questions/7867361/object-save-failed-in-spec-data-validation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!