2013-09-03 2 views
0

В настоящее время я разрабатываю приложение RoR 4.Понимание тестов пользователей RSPEC в учебнике Ruby on Rails

В моем приложении я пытаюсь реализовать тесты пользователей, подобные учебнику Микаэля Хартла. Я хотел бы узнать несколько вещей о тесте уникальности eMail:

1 - Уникальность проверяется при фактическом написании в базе данных, не так ли?

При написании моего теста так же, как в учебнике, он неэффективен. @user = User.new (...) фактически создает экземпляр пользователя только в памяти. Следующий тест:

describe "when email address is already used" do 
    before do 
    user_with_same_email = @user.dup 
    user_with_same_email.save 
    end 

    it { should_not be_valid } 
end 

работает только в моем случае, когда @user = user.new (...) инструкция сопровождается инструкцией user.save. Я прав ?

Дополнительное примечание:, когда уникальная электронная почта реализована в пользовательской модели, она всегда терпит неудачу!?! Можете ли вы рассказать мне, что не так с этим тестом?

VALID_EMAIL_REGEX = /\A[\w+\-.][email protected][a-z\d\-.]+\.[a-z]+\z/i 
validates :email, presence: true, uniqueness: true, length: { maximum: 100 }, format: { with: VALID_EMAIL_REGEX } 

2 - Действительно ли RSPEC пишет в базу данных TEST?

После выполнения вышеуказанного теста (user.new (...) - user.save - user.dup - user.save), я проверяю «измененную дату» файла базы данных TEST SQLite3. При тестировании он не был затронут. Файлы spec_hepler.rb начинаются с:

ENV["RAILS_ENV"] ||= 'test' 

Я что-то пропустил?

Спасибо за вашу помощь,

С наилучшими пожеланиями,

Фред

ответ

1

О вашей первой точки, проверка на уникальность действительно происходит, когда вы звоните save. Однако вы также можете вызвать все проверки, позвонив по телефону valid? - что и делает be_valid. Поэтому на самом деле не нужно сохранять модель @user для этого теста.

О вашей второй точке, RSpec абсолютно пишет в базу данных. Тем не менее, он запускает каждый тест в пределах транзакции (по умолчанию). В конце каждого теста вместо совершения транзакции он откатывает его. Это оставляет базу данных в том же состоянии, что и до начала теста, эффективно позволяя изолировать каждый тест от других при использовании базы данных точно так же, как ваш код будет работать (почти). Что касается вашей точки времени изменения файла, SQLite не обязательно записывает данные в файл при выполнении вызовов до тех пор, пока они не будут выполнены.

+0

Спасибо за ваше объяснение по поводу SQLite, теперь ясно. – user1185081

+0

О структуре тестирования уникальности, вы имеете в виду, что последовательность команд user1 = User.new() - user2 = user1.dup - user2.save действительно запускает тест уникальности при выполнении инструкции сохранения? – user1185081

+0

@ user1185081: В рамках подготовки теста 'user2.save' запускает проверки, но условие уникальности считается выполненным в этой точке, поскольку' user1' еще не сохраняется в базе данных. Затем тест проверяет, действительно ли 'user1' - возвращает false (как и ожидалось), так как' user2' уже был сохранен с этим адресом электронной почты. – PinnyM

Смежные вопросы