自定义验证在开发中有效,但在单元测试中无效

时间:2010-06-14 11:48:41

标签: ruby-on-rails validation

我想验证两列中至少有一列在我的模型中有值。我在网上找到了我可以创建自定义验证器的地方,如下所示:

# Check for the presence of one or another field:
#  :validates_presence_of_at_least_one_field :last_name, :company_name  - would require either last_name or company_name to be filled in
#  also works with arrays
#  :validates_presence_of_at_least_one_field :email, [:name, :address, :city, :state] - would require email or a mailing type address

module ActiveRecord
  module Validations
    module ClassMethods

      def validates_presence_of_at_least_one_field(*attr_names)
        msg = attr_names.collect {|a| a.is_a?(Array) ? " ( #{a.join(", ")} ) " : a.to_s}.join(", ") + "can't all be blank.  At least one field must be filled in."
        configuration = { :on => :save, :message => msg }
        configuration.update(attr_names.extract_options!)
        send(validation_method(configuration[:on]), configuration) do |record|
          found = false
          attr_names.each do |a|
            a = [a] unless a.is_a?(Array)
            found = true
            a.each do |attr|
              value = record.respond_to?(attr.to_s) ? record.send(attr.to_s) : record[attr.to_s]
              found = !value.blank?
            end
            break if found
          end
          record.errors.add_to_base(configuration[:message]) unless found
        end
      end

    end
  end
end

我把它放在我的项目中名为lib / acs_validator.rb的文件中,并将“require'acs_validator'”添加到我的environment.rb中。这正是我想要的。当我在开发环境中手动测试它时它非常有效,但是当我编写单元测试时,它会破坏我的测试环境。

这是我的单元测试:

require 'test_helper'

class CustomerTest < ActiveSupport::TestCase
  # Replace this with your real tests.
  test "the truth" do
    assert true
  end
  test "customer not valid" do
    puts "customer not valid"
    customer = Customer.new
    assert !customer.valid?
    assert customer.errors.invalid?(:subdomain)
    assert_equal "Company Name and Last Name can't both be blank.", customer.errors.on(:contact_lname)
  end
end

这是我的模特:

class Customer < ActiveRecord::Base
  validates_presence_of :subdomain
  validates_presence_of_at_least_one_field :customer_company_name, :contact_lname, :message => "Company Name and Last Name can't both be blank."

  has_one :service_plan

end

当我运行单元测试时,出现以下错误:

DEPRECATION WARNING: Rake tasks in vendor/plugins/admin_data/tasks, vendor/plugins/admin_data/tasks, and vendor/plugins/admin_data/tasks are deprecated. Use lib/tasks instead. (called from /usr/lib/ruby/gems/1.8/gems/rails-2.3.8/lib/tasks/rails.rb:10)
Couldn't drop acs_test : #<ActiveRecord::StatementInvalid: PGError: ERROR:  database "acs_test" is being accessed by other users
DETAIL:  There are 1 other session(s) using the database.
: DROP DATABASE IF EXISTS "acs_test">
acs_test already exists
NOTICE:  CREATE TABLE will create implicit sequence "customers_id_seq" for serial column "customers.id"
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "customers_pkey" for table "customers"
NOTICE:  CREATE TABLE will create implicit sequence "service_plans_id_seq" for serial column "service_plans.id"
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "service_plans_pkey" for table "service_plans"
/usr/bin/ruby1.8 -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/unit/customer_test.rb" "test/unit/service_plan_test.rb" "test/unit/helpers/dashboard_helper_test.rb" "test/unit/helpers/customers_helper_test.rb" "test/unit/helpers/service_plans_helper_test.rb" 
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/base.rb:1994:in `method_missing_without_paginate': undefined method `validates_presence_of_at_least_one_field' for #<Class:0xb7076bd0> (NoMethodError)
    from /usr/lib/ruby/gems/1.8/gems/will_paginate-2.3.12/lib/will_paginate/finder.rb:170:in `method_missing'
    from /home/george/projects/advancedcomfortcs/app/models/customer.rb:3
    from /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
    from /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
    from /usr/lib/ruby/gems/1.8/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:158:in `require'
    from /usr/lib/ruby/gems/1.8/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:265:in `require_or_load'
    from /usr/lib/ruby/gems/1.8/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:224:in `depend_on'
    from /usr/lib/ruby/gems/1.8/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:136:in `require_dependency'
    from /usr/lib/ruby/gems/1.8/gems/rails-2.3.8/lib/initializer.rb:414:in `load_application_classes'
    from /usr/lib/ruby/gems/1.8/gems/rails-2.3.8/lib/initializer.rb:413:in `each'
    from /usr/lib/ruby/gems/1.8/gems/rails-2.3.8/lib/initializer.rb:413:in `load_application_classes'
    from /usr/lib/ruby/gems/1.8/gems/rails-2.3.8/lib/initializer.rb:411:in `each'
    from /usr/lib/ruby/gems/1.8/gems/rails-2.3.8/lib/initializer.rb:411:in `load_application_classes'
    from /usr/lib/ruby/gems/1.8/gems/rails-2.3.8/lib/initializer.rb:197:in `process'
    from /usr/lib/ruby/gems/1.8/gems/rails-2.3.8/lib/initializer.rb:113:in `send'
    from /usr/lib/ruby/gems/1.8/gems/rails-2.3.8/lib/initializer.rb:113:in `run'
    from /home/george/projects/advancedcomfortcs/config/environment.rb:9
    from ./test/test_helper.rb:2:in `require'
    from ./test/test_helper.rb:2
    from ./test/unit/customer_test.rb:1:in `require'
    from ./test/unit/customer_test.rb:1
    from /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb:5:in `load'
    from /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb:5
    from /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb:5:in `each'
    from /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb:5
rake aborted!
Command failed with status (1): [/usr/bin/ruby1.8 -I"lib:test" "/usr/lib/ru...]

(See full trace by running task with --trace)

似乎已经以某种方式踩到了will_paginate。

有没有人有任何建议?还有另一种方法可以进行我正在尝试的验证吗?

谢谢, 乔治

1 个答案:

答案 0 :(得分:0)

如果它正在开发并且在测试数据库中失败。我怀疑它是否适用于迁移。 我希望运行rake db:test:load应该解决问题