Object.save在规范数据validation中失败

以下是客户控制器中创建的失败规范代码:

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 

客户的销售ID和类别ID分别属于用户和类别表。

这是规范失败错误:

  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 ' 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 ' 

以下是在客户控制器中创建的应用程序代码:

  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 

这是在factory.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 

似乎该错误是由@ customer.save返回false引起的,并且“if @ customer.save”的代码未执行。 所以问题可能出在Factory生成的@customer上,这对我来说似乎很好。 保存客户时,代码执行没有任何问题。

有什么建议? 谢谢。

我会将其分解为两个特定的测试。 现在你不确定两件事:

  1. 是客户被告知自救?
  2. 是否存在阻止客户保存的validation?

最快的方法是将@ customer.save更改为@ customer.save! 并查看是否有任何exception引发(如果validation失败,它将执行此操作)。

我建议你把它分开。 要测试#1,在控制器规范中:

 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 

然后在您的customer_spec中测试:

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

用上面的方法解决了这个问题。