Используйте .new или .create! при тестировании моделей Rails с помощью Rspec?

#ruby-on-rails #unit-testing #rspec

#ruby-on-rails #модульное тестирование #rspec

Вопрос:

У меня есть таблица контактов в приложении Rails 3.1. Я хочу, чтобы last_name принимал 40 символов, поэтому в моей модели я написал :length => { :maximum => 40 } . Однако из-за опечатки в моей миграции был создан столбец last_name :limit => 30 .

Я задавался вопросом, почему мой тест Rspec не обнаружил этого:

 it "should allow last_name up to max length" do
  long_field = "a" * 40
  Contact.new(@attr.merge(:last_name => long_field)).should be_valid
end
  

затем я понял, что это только проверка модели. Если я использую .create! вместо этого, тест завершается с ошибкой:

 it "should allow last_name up to max length" do
  long_field = "a" * 40
  Contact.create!(@attr.merge(:last_name => long_field)).should be_valid
end
  

Итак, вопрос в том, должен ли я всегда использовать .create! при тестировании своих моделей? Или это слишком медленно? Как еще я могу убедиться, что определения моей модели и базы данных не конфликтуют?

Это также заставляет меня задуматься, должен ли я просто оставить строки как 255 в базе данных и проверять только длину в модели.

Ответ №1:

Вы должны использовать .new как можно больше по соображениям скорости. И чтобы ваш тест не прошел, вы должны использовать validates_length_of . Что касается длины строки, в идеале они должны совпадать, и если вы чувствуете себя слишком тщательно, вы можете подумать о проверках и Model.columns, чтобы убедиться, что у вас есть проверка для каждого столбца.

Комментарии:

1. Наконец, возвращаясь к деталям этого. Я использую :validates :length вместо :validates_length_of , но любой из них позволяет пройти тест, если используется тест rspec :new . Другими словами, если средство проверки модели корректно, но поле DB слишком короткое, :new тест проходит, потому что он не выполняет запись в базу данных. Я не думаю, что отражение поможет, потому что оно также не проверяет базу данных. Кажется странным, что миграция <-> синхронизация модели выполняется вручную. Пока :create! я вижу единственный способ проверить, принимает ли БД то, что ей даст модель.