Rspec - 如何为 class 方法编写测试

Rspec - how to write a test for class method

作为 RoR 的新手,Rspec 我正在努力为这种情况编写测试。

# Table name: countries
#
#  id             :integer          not null, primary key
#  code           :string(255)      not null
#  name           :string(255)
#  display_order  :integer
#  create_user_id :integer          not null
#  update_user_id :integer
#  created_at     :datetime         not null
#  updated_at     :datetime
#  eff_date       :date
#  exp_Date       :date

我想在国家模型中测试这个方法:

 def self.get_default_country_name_order
        countries = Country.in_effect.all.where("id !=?" ,WBConstants::DEFAULT_COUNTRY_ID).order("name")
    result = countries
  end

在我的 country_spec 我有这个:

describe Country do
  before(:all) do
    DatabaseCleaner.clean_with(:truncation)
  end
  let(:user){create(:user)}
  let(:country3){create(:country,code:"AUS", name:"Australia", create_user:user, eff_date: Time.new(9999,12,31), exp_date: Time.new(9999,12,31))}

  after(:all) do
    DatabaseCleaner.clean_with(:truncation)
  end

这个国家/地区将过期,模型上有一个命名范围,可以过滤掉过期的国家/地区。我的测试应该是这样的:

it "should not include an expired country" do
   c = Country.get_default_country_name_order
  end

到目前为止这是正确的吗?测试似乎没有 return 任何来自方法的东西?

是的,这是正确的方向。

要解决持久化 Country 模型的问题,您应该更改此设置:

let(:country3){create(:country,code:"AUS", name:"Australia", create_user:user, eff_date: Time.new(9999,12,31), exp_date: Time.new(9999,12,31))}

对此:

before {create(:country,code:"AUS", name:"Australia", create_user:user, eff_date: Time.new(9999,12,31), exp_date: Time.new(9999,12,31))}

或在您的测试电话中 :country3:

it "should not include an expired country" do
  country3
  c = Country.get_default_country_name_order
end

let(:country3) 只是 "registering" 一个要调用的方法(在您的示例中,它填充数据库),但它不会自动执行。只要您不需要从此方法返回值,就应该坚持使用 before,它将自动执行代码。

另一方面,您可能想要测试 Country 模型的返回值。类似于:

it "should not include an expired country" do
  example_country = country3
  c = Country.get_default_country_name_order
  expect(c).to eq example_country
end

希望对您有所帮助。

祝你好运!

更新

如何使用多次出现的 before

构建规范的示例
describe Country do
  before(:all) do
    DatabaseCleaner.clean_with(:truncation)
  end
  let(:user){create(:user)}
  let(:country3){create(:country,code:"AUS", name:"Australia", create_user:user, eff_date: Time.new(9999,12,31), exp_date: Time.new(9999,12,31))}

  after(:all) do
    DatabaseCleaner.clean_with(:truncation)
  end

  describe "#get_default_country_name_order" do
    # you can register another "before"
    before {create(:country,code:"AUS", name:"Australia", create_user:user, eff_date: Time.new(9999,12,31), exp_date: Time.new(9999,12,31))}

    # or simpler - this will call your method 
    # before "it", and create the record
    # before { country3 }

    it "should not include an expired country" do
      # your expectations here
    end
  end