TypeError:错误的参数类型String(预期的模块)

时间:2011-12-05 12:03:54

标签: ruby-on-rails ruby metaprogramming rspec2

我有以下代码:

class ProfileLookup < ActiveRecord::Base
  class << self
    ProfileLookup.select("DISTINCT category").map{|c| c.category}.each do |category|
      define_method("available_#{category.pluralize}".to_sym) do
        ProfileLookup.where(category: category).order(:value).all.collect{|g| g.value}
      end
    end
  end
end

基本上包含一大堆查找数据,按类别拆分。目的是为数据库中的每个类别创建一个方法。通过Rails控制台,此代码按预期工作:

ruby-1.9.3@hub :002 > ProfileLookup.available_genders
  ProfileLookup Load (0.6ms)  SELECT "profile_lookups".* FROM "profile_lookups" WHERE "profile_lookups"."category" = 'gender' ORDER BY value
 => ["Female", "Male"] 

但是,我的规格都失败了。以下规范:

require "spec_helper"

describe ProfileLookup do

  its(:available_genders).should include("Male")
  its(:available_age_groups).should include("0-17")
  its(:available_interests).should include("Autos & Vehicles")
  its(:available_countries).should include("United States")

end

失败了:

Exception encountered: #<TypeError: wrong argument type String (expected Module)>
backtrace:
/Users/fred/code/my_app/spec/models/profile_lookup_spec.rb:5:in `include'

这里有什么问题?

3 个答案:

答案 0 :(得分:3)

首先,its的语法错误,您应该use the block form

its(:available_genders) { should include("Male") }

其次,当你describe一个类时,你匹配的主题是该类的实例

https://www.relishapp.com/rspec/rspec-core/docs/subject/implicit-subject

  

如果最外层示例组的第一个参数是一个类,则通过subject()方法向每个示例公开该类的实例。

你可以明确这个主题,一切都会奏效:

require "spec_helper"

describe ProfileLookup do

  subject { ProfileLookup }

  its(:available_genders) { should include("Male") }
  its(:available_age_groups) { should include("0-17") }
  its(:available_interests) { should include("Autos & Vehicles") }
  its(:available_countries) { should include("United States") }

end

答案 1 :(得分:0)

为什么这不起作用有几个原因:

  • 隐式主题似乎不适用于静态方法
  • 您的示例需要一个上下文或it块:

此代码有效:

require "spec_helper"

describe ProfileLookup do

  it 'should know what lookups are available' do
    ProfileLookup.available_genders.should include("Male")
    ProfileLookup.available_age_groups.should include("0-17")
    ProfileLookup.available_interests.should include("Autos & Vehicles")
    ProfileLookup.available_countries.should include("United States")
  end

end

答案 2 :(得分:0)

include方法通常用于将模块包含到类(或其他模块)中。看起来他们没有覆盖include范围内的describe,只覆盖it范围。