【问题标题】:Object.save failed in spec data validationObject.save 在规范数据验证中失败
【发布时间】:2011-10-23 16:14:02
【问题描述】:

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

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

这是在客户控制器中创建的应用代码:

  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 上,这对我来说似乎很好。保存客户时,代码执行没有任何问题。

有什么建议吗?谢谢。

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3.1 rspec2


    【解决方案1】:

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

    1. 客户是否被告知要自救?
    2. 是否存在阻止客户获救的验证?

    最快的方法是将@customer.save 更改为@customer.save!并查看是否引发了任何异常(如果验证失败,它将这样做)。

    我建议你把它分开。要测试 #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
    

    【讨论】:

    • 我将您的代码添加到控制器的规范中。这是错误消息:1)CustomersController GET客户页面'create'成功应该告诉客户在有会话时保存自己[:sales]失败/错误:Customer.stub(:new => cutomer_mock)NameError:未定义本地' 中的变量或方法cutomer_mock' for #&lt;RSpec::Core::ExampleGroup::Nested_2::Nested_1::Nested_1:0x43d4d98&gt; # ./spec/controllers/customers_controller_spec.rb:41:in block(4 级)
    • 2) CustomersController GET 客户页面“创建”成功应该与工厂规格有效失败/错误:customer.should be_valid 预期有效吗?返回 true,得到 false # ./spec/controllers/customers_controller_spec.rb:47:in `block (4 levels) in '
    • 对于第一个示例,您可能没有正确输入代码。其次,这证明了验证正在妨碍您。接下来的步骤取决于您。
    • 您是否发现 Factory 创建的示例数据有任何问题?我认为有问题但看不到。
    • 我真的无法判断这一点。这取决于您的工厂定义和您为模型定义的验证。
    【解决方案2】:
    post :create, :customer => @customer
    

    解决了上面的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-19
      • 2011-02-03
      • 1970-01-01
      • 1970-01-01
      • 2012-07-14
      • 2016-09-05
      相关资源
      最近更新 更多