RSpec中动态define_method抛出错误

时间:2011-05-16 17:46:57

标签: ruby-on-rails-3 activerecord metaprogramming rspec2

我很确定我在这里错过了一个基本的错误,所以我希望另一组眼睛可能有所帮助。我正在使用Rails 3,Ruby 1.9.2和Rspec 2。

我想在模型上定义动态类方法,以便在将可分配对象(例如帐户)添加到系统时返回基本角色。例如:

BaseRole.creator_for_account

通过控制台一切正常:

ruby-1.9.2-p180 :003 > BaseRole.respond_to?(:creator_for_account)
 => true 

但是当我为任何类方法运行我的规范时,无论在哪里调用规范中的方法,我都会得到NoMethodError。我假设关于我如何动态地声明这些方法的东西不是用RSpec来讨价还价,但我似乎无法弄明白为什么。

lib dir是自动加载路径,对于respond_to,方法返回true。

# /lib/assignable_base_role.rb
module AssignableBaseRole
  def self.included(base)
    base.extend(ClassMethods)
  end

  module ClassMethods
    BaseRole.all.each do |base_role|
      role_type = RoleType.find(base_role.role_type_id)
      assignable_name = base_role.assignable_type.downcase
      method = "#{role_type.name}_for_#{assignable_name}"

      define_method(method) do
        self.where(:role_type_id => role_type.id,
                :assignable_type => assignable_name).first
      end
    end 
  end
end

然后在BaseRole中包含模块

# /models/base_role.rb
class BaseRole < ActiveRecord::Base
  include AssignableBaseRole

  belongs_to :role
  belongs_to :role_type

  ......
  ......

end

然后在我的规范中:

  it "adds correct authority for creator role" do
    create_assignment 
    base_role = BaseRole.creator_for_account # <== NoMethodError here
    user1 = Factory.create(:user)
    account.users << user1
    user1.roles_for_assignable(account).should include(base_role.role)
  end

2 个答案:

答案 0 :(得分:1)

您的项目中是否有另一个类或具有相同名称的规范,但是没有添加动态方法?我和你有完全相同的问题,并重命名其中一个类修复它。

我的猜测是其他课程首先加载

答案 1 :(得分:0)

您似乎正在根据数据库中的值定义这些方法:

BaseRole.all.each do |base_role|
.....

可能是#34;创作者&#34;在测试数据库中不作为角色类型存在,或者&#34;帐户&#34;不作为assignable_type存在?

据推测,您正在控制台中进行测试以进行开发,而不是测试,因此数据可能不匹配。可能需要在before hook中设置数据。