关于使用rspec测试模型的建议

时间:2011-07-24 15:37:01

标签: ruby-on-rails rspec shoulda

我刚开始使用rspec,我想就此规范发表看法。 我有2个型号

class City < ActiveRecord::Base
  validates :name, :presence => true, :uniqueness => true
  validates :department_id, :presence => true
  belongs_to :department
end

class Department < ActiveRecord::Base
  validates :name, :presence => true, :uniqueness => true
  has_many :cities
end

我写下这些规范是为了满足验证和关系声明:

city_spec.rb

describe City do

  before(:each) do
    @city = Factory(:city)
  end

  describe "validation" do
    it "valid" do
      @city.should be_valid
      @city.should have(:no).errors_on(:name)
      @city.should have(:no).errors_on(:department_id)
    end

    it "has a unique name" do
      c = Factory.build(:city, :name => @city.name)
      c.should_not be_valid
      c.name = 'unique'
      c.should be_valid
      # or via shoulda
      c.should validate_uniqueness_of(:name)
    end

    it "belongs to department" do
      c = Factory.build(:city, :department_id => nil)
      c.should have(1).error_on(:department_id)
      c.department_id = @city.department_id
      c.should be_valid
      c.should belong_to(:department)
    end
  end
end

department_spec.rb

describe Department do

  before(:each) do
    @department = Factory(:department)
  end

  describe "validation" do
   it "has a name" do
    d = Factory.build(:department, :name => nil)
    d.should_not be_valid
    d.should have(1).error_on(:name)
    d.name = 'good name'
    d.should be_valid
  end

  it "has a unique name" do
    d = Factory.build(:department, :name => @department.name)
    d.should_not be_valid
    d.name = 'good name'
    d.should be_valid
  end

  it "has many cities" do
    d = Factory.build(:department)
    c1 = Factory.build(:city)
    c2 = Factory.build(:city)
    d.cities << c1
    d.cities << c2
    d.cities.size.should == 2
    d.cities.first.should == c1
    d.cities.last.should == c2
    # or via shoulda
    d.should have_many(:cities)
 end
 end
 end

你可以看到我也使用了shoulda gem,你认为这种方法是否正确?我为这个函数写了太多测试? 谢谢

2 个答案:

答案 0 :(得分:0)

快速浏览一下,您似乎专注于测试模型对象的状态。那完全没问题。我唯一能看到的是这些模型中的任何一个都有相关的行为吗?它们是否包含实现业务逻辑的任何方法?如果没有,那我就是自由的,我相信。如果你这样做,那么我会为这些行为添加测试。

答案 1 :(得分:0)

我肯定会建议你测试你的模型:

使用rspec时,您应该在gem文件的测试组中使用shoulda-matchers gem:

gem 'shoulda-matchers', :require => false

在您的spec_helper.rb中,在require 'shoulda-matchers'之后添加require 'rspec/rails'

然后你只需使用以下测试:

city_spec.rb

it { should validate_prescence_of(:name) }
it { should validate_prescence_of(:department_id) }
it { should belong_to(:department) }

对于唯一性测试,您需要在测试之前创建城市实例,然后使用:

it { should validate_uniqueness_of(:name) }

正如您所看到的 - 比您所写的更清晰,更清晰的测试。