测试method_defined?ActiveRecord 类在实例化之前不起作用 [英] testing for method_defined? on ActiveRecord classes doesn't work until an instantiation

查看:48
本文介绍了测试method_defined?ActiveRecord 类在实例化之前不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在测试与 ActiveRecord 的数据库列对应的方法时遇到问题.使用您拥有的任何模型(在我的情况下为 Document),然后执行以下操作:

$ rails c加载开发环境(Rails 3.0.9)>>Document.method_defined?(:id)=>错误的>>新建文件=>#<文档id:nil,feed_id:nil>>>Document.method_defined?(:id)=>真的

显然有一些 ActiveRecord 生命周期工作正在进行,作为 .new() 的先决条件,即将所有数据库列作为方法添加到类中.

真正使事情复杂化的地方是在单元测试期间.我想要一个在运行时接受 ActiveRecord 类并对它们进行一些验证的类

例如

class Foo 

我可以做些什么来断言(除了使用 .new() 创建垃圾实例)ActiveRecord 已完成其初始化?

解决方案

这似乎是一个错误,但不太可能很快得到修复.

不一致的method_defined?行为

我发现了 .attribute_method?在课堂上工作以做您需要的事情.您可以在 ActiveRecord::AttributeMethods::ClassMethods 中找到更多信息>

I'm having a problem testing for methods that correspond to the database columns of an ActiveRecord. Take any model you've got (in my case Document), and do the following:

$  rails c
Loading development environment (Rails 3.0.9)
>> Document.method_defined?(:id)
=> false
>> Document.new
=> #<Document id: nil, feed_id: nil >
>> Document.method_defined?(:id)
=> true

There is obviously some ActiveRecord lifecycle work going on as a prerequisite to .new() that's adding all the database columns as methods to the class.

Where this really complicates things is during unit testing. I'd like have a class that in runtime accepts ActiveRecord classes and does some validation on them

For example

class Foo < ActiveRecord::Base
  def work1
    # something
  end
end
class Command
  def operates_on(clazz, method)
    # unless I add a "clazz.new" first, method_defined? will fail 
    # on things like :id and :created_at
    raise "not a good class #{clazz.name}" if ! clazz.method_defined?(method)
    # <logic here>
  end
end

describe Command do
  it "should pass if given a good class" do
    Command.new.operates_on(Foo,:work1)
  end
  it "should pass if given a database column" do
    # this FAILS
    Command.new.operates_on(Foo,:id)
  end
  it "should raise if given an invalid class/method combo" do
    lambda { Command.new.operates_on(Foo,:non_work) }.should raise_error
  end
end

What can I do to assert (other than making a junk instance with .new()) that the ActiveRecord has done its initialization?

解决方案

This appears to be a bug but isn't likely going to be fixed soon.

Inconsistent method_defined? behaviour

I found that .attribute_method? works on the class to do what you need. You can find more information at ActiveRecord::AttributeMethods::ClassMethods

这篇关于测试method_defined?ActiveRecord 类在实例化之前不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆