совет по использованию rspec для тестирования модели

Я только начал использовать 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. Как вы думаете, этот подход правильный? Я написал слишком много тестов для этой функции? Спасибо


person Mattia Lipreri    schedule 24.07.2011    source источник


Ответы (2)


На первый взгляд кажется, что вы сосредоточены на тестировании состояния объектов модели. Это совершенно нормально. Единственное, на что я бы посмотрел, есть ли у любой из этих моделей какое-либо связанное поведение? Содержат ли они какие-либо методы, реализующие бизнес-логику? Если нет, то, я полагаю, вы дома свободны. Если вы это сделаете, я бы добавил тесты для такого поведения.

person jaydel    schedule 24.07.2011
comment
прямо сейчас у меня нет никакого метода о бизнес-логике, я просто тестировал rspec, и я спросил об этом, потому что мне нужен отзыв о том, что я сделал, просто чтобы знать, на правильном ли я пути. Большое спасибо - person Mattia Lipreri; 25.07.2011

Я определенно предложил бы для тестирования ваших моделей:

При использовании rspec вы должны использовать гем shoulda-matchers в тестовой группе вашего файла гем:

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) }

Как видите - гораздо чище и понятнее тесты, чем то, что вы написали.

person nmott    schedule 18.10.2011
comment
как бы вы проверили валидацию :account_id, :numericality =› {:greater_then =› 0}, используя shoulda? - person Nazgob; 04.03.2012
comment
@Nazgob Я бы разделил тесты it { should validate_numericality_of(:account_id) }, а затем it { should allow_value(0).for(:account_id) } it { should_not allow_value(-1).for(:account_id) - person nmott; 05.03.2012
comment
Хорошо, было бы неплохо иметь это в одной проверке, идея для запроса на вытягивание? :) - person Nazgob; 06.03.2012