#ruby-on-rails #ruby-on-rails-3 #sqlite #rspec
#ruby-on-rails #ruby-on-rails-3 #sqlite #rspec
Вопрос:
У меня странная проблема с моим набором тестов Rspec. Все тесты, которые вставляют данные в таблицу с уникальным ограничением, завершаются неудачей. Запуск неудачных тестов по отдельности путем указания номера строки работает так, как ожидалось.
Чтобы исследовать проблему, я напечатал количество строк в этой таблице перед вставкой данных, вызывающих исключение ограничения, и сообщает, что таблица пуста.
Нет ни before :all
в одном файле вообще.
Я использую DatabaseCleaner, и, за исключением этой проблемы, кажется, что очистка работает.
Это, например, не работает при запуске всего файла:
describe User
# ...
describe '#follow_location' do
let(:user) { Factory(:user) }
let(:location) { Factory(:location) }
it 'should raise when trying to follow an already followed location' do
puts LocationFollowship.count # => 0
user.followed_locations << location # exception raised
lambda {
user.follow_location location
}.should raise_error User::AlreadyFollowingLocation
end
end
# …
end
Редактировать:
Я смог отследить его. Это связано с Rails, использующим кэшированный оператор. Вызов ActiveRecord::Base.connection.clear_cache!
заставляет его работать. Но добавление этого фрагмента в spec_helper.rb вызывает исключение SQLite cannot use a closed statement
.
Комментарии:
1. можете ли вы показать нам свои фабрики? 🙂 возможно, вы добавили поле id
2. Они вообще не устанавливают никаких явных идентификаторов.
Ответ №1:
У меня тоже была эта проблема. Кроме того, интерпретатор Ruby при определенных условиях выполнял ошибку segfault, когда я пытался ее исследовать (вероятно, вызванный SQLite).
У меня объявлен уникальный индекс, например:
add_index(:table, [:column1, :column2], unique: true)
Добавление следующего ограничения уникальности в модель (в дополнение к существующему индексу при миграции) устранило проблему:
validates_uniqueness_of :column1, scope: :column2