Rails, state_machine, Rspec, capybara, factory_girl, spork и другое. Часть III.
В предыдущих частях мы закончили настраивать наше тестовое окружение. Теперь с чистой, так сказать, совестью можем приступать к написанию самих тестов и дальнейшему развитию приложения.
22. И начнём с «фабричных девчёнок: factory_girl. Этот замечательный gem необходим для того, чтобы упростить создание примеров объектов, которые используются в тестах. Например, чтобы каждый раз не создавать и не повторяться в разных тестах при создании нового пользователя, можно отлично использовать factory_girl. Итак, создадим файл spec/factories.rb для начала следующего содержания:
FactoryGirl.define do
factory :user do
name ‘none’
email ‘none@example.com’
password ’1111111111′
end
end
Здесь мы задали параметры для вновь создаваемого пользователя. Не забудьте добавить в spec/spec_helper.rb:
require ‘factory_girl’
23. Теперь открываем файл spec/models/user_spec.rb. Сейчас он должен быть практически пустым:
require ‘spec_helper’
describe User do
end
Теперь вставим следующий фрагмент кода сразу же за директивой describe User do:
before(:each) do
user = Factory(:user)
end
Данный блок, как следует из его названия и определения, перед (before) каждым (each) тестом создавать нам пользователя, которого мы можем использовать в тестах.
24. Давайте напишем первые наши тесты. Сразу же за блоком before пишем следующее:
it ‘should create a new user with state new’ do
newuser = User.new(@user)
newuser.new?.should be_true
end
it ‘should create a new user with state not eq active’ do
newuser = User.new(@user)
newuser.active?.should be_false
end
it ‘should create a new user with state not eq blocked’ do
newuser = User.new(@user)
newuser.blocked?.should be_false
end
Все тесты имеют одинаковую структуру:
it ‘ожидание от теста’ do
выполнение каких-либо действий, проверок
end
Первый наш тест создаёт нового пользователя и проверяет его состояние — оно должно быть new:
newuser.new?.should be_true
Не удивляйтесь и не пугайтесь, если эта запись немного не понятна. Что вообще за «new?» и откуда оно взялось? Всё по порядку, позже объясню. Эту запись можно переписать другим способом, даже более понятным образом:
newuser.state.should eq(«new»)
Это как-то больше похоже на человеческий язык, правда, английский: «статус созданного пользователя должен быть эквивалентен новому». Для задания и изменения статуса мы будем использовать замечательный gem state_machine. Если кто-нибудь из читателей знаком с понятием «конечные автоматы», то ничего нового он не узнает. Для тех же, кто не в курсе, то state_machine — это способ описания состояний автомата, в нашем случае — это записи в таблице User, а так же методы перехода из одного состояния в другое.
Так как это не настоящее приложение, а так, для потренироваться, то я предположил, что Пользователи будут иметь всего три состояния:
1. new — это только что созданный пользователь
2. active — это пользователь, который активированный и может выполнять какие-либо действия
3. blocked — это заблокированный пользователь, соответственно, он ничего не может сделать
Это, иными словами, описание состояний автомата. Чуть позже опишу о способах изменения состояния, а пока обращаю Ваше внимание, что приведённые выше тесты не проходят, да… Что ж, давайте мелкими шажками делать, чтоб эти тесты проходили (-:
25. Описание state_machine очень неплохо документировано, настоятельно рекомендую ознакомиться с содержимым сайта. Я же предлагаю открыть открыть файл нашей модели app/models/user.rb и вписать туда следующее:
state_machine :initial => :new do
end
Этим самым мы описываем начальное состояние нашего конечного автомата. По умолчанию state_machine как раз и использует поле state, которое мы указали при генерации модели. Как видно из приведённой выше записи, начальное состояние будет «new». Но это ещё не всё (-: Кроме задания первоначального состояния в «new», state_machine даёт нам в помощь некоторые вспомогательные методы, которые дают нам возможность проверить состояние автомата. Один из них «new?», который возвратит «истина», если, как говорят у нас в Одессе, «состояние таки да new», и «ложь», если какое-то другое. Именно этот метод мы использовали в выражении «newuser.new?.should be_true«: а правда ли, что состояние нового пользователя есть «new»? (-: Ну что-то типа того.
26. После сохранения внесённых изменений, первый наш тест должен проходить! Ура, товарищи! (((-: Но только один из трёх… на оставшиеся должно выдавать ошибку, что-то типа этой:
1) User should create a new user with state not eq active
Failure/Error: newuser.active?.should be_false
NoMethodError:
undefined method `active?’ for #<User:0xb09a500>
# ./spec/models/user_spec.rb:23:in `block (2 levels) in <top (required)>’
Надо с этим что-то делать (-: А сделать надо простою вещь: добавить в наш файл модели две строчки
state :active
state :blocked
Иными словами, описать ещё два доступных состояния, которые мы пытаемся проверить во 2м и 3м тестах. После сохранения файла модели, все тесты должны пройти успешно!
В следующий раз я продолжу написание тестов и дальнейшее развитие нашего проекта.
Недавние записи
- Long time no see
- Ошибка при обновлении Meteor до версии 1.4.2
- Patch falcon для ruby-1.9.3-p327
- Ускоряем ruby и Rails
- Gem ‘seo_params’: определение основных параметров
- Отрицательный margin-top и Opera
- Rspec and Devise reset password
- Backbone.js: Views. Часть первая.
- Backbone.js: Models and Collections
- Backbone.js Routers
Ноябрь 27th, 2011 at 23:55
Нужно детальней прописать, что state [:active, :blocked] нужно писать в блок state_machine {} do .. end
class User :new do
state :active
state :blocked
end
end
Вообщем очень помогла еще дока /path/to/ruby/gems/state_machine-1.1.0/lib/state_machine/machine.rb
ЗЫ спасибо за статьи.
Ноябрь 28th, 2011 at 00:04
Ваша система комментов жрёт код О_о
между class User и :new do
стояло это
»
левая стрела ActiveRecord::Base
state_machine :initial =права стрела
»
может ваш XSS протект перестарался