Записи с меткой ‘module’
Тестирование модулей с помощью RSpec
К примеру, у нас есть такой модуль, который мы добавляем в классы Airport, City:
extend ActiveSupport::Concern
module InstanceMethods
def name locale=:en
locale = :en if !name_ru || name_ru.empty?
send(name_method(locale))
end
def localized_name
name(I18n.locale || :en)
end
private
def name_method locale=:en
"name_#{locale}".to_sym
end
end
included do
field :name_en, :type => String
field :name_ru, :type => String
validates_presence_of :name_en
end
end
include Mongoid::Document
include Nameable
end
include Mongoid::Document
include Nameable
end
Чтобы протестировать модуль, для него нужно создать shared_examples_for блок:
it{should have_fields(:name_en).of_type(String)}
it{should have_fields(:name_ru).of_type(String)}
it{should validate_presence_of(:name_en)}
describe '#name' do
specify{nameable.name(:en).should == 'Name'}
specify{nameable.name(:ru).should == 'Имя'}
context 'if russian name is null' do
before do
nameable.name_ru = nil
end
specify{nameable.name(:en).should == 'Name'}
specify{nameable.name(:ru).should == 'Name'}
end
end
# И так далее...
end
В блоке используется одна переменная nameable, которая будет определяться в спеке того класса, к которому мы подключим модуль. То есть в spec/models/airport_spec.rb пишем примерно так:
require 'models/nameable_spec'
describe Airport do
it{should be_mongoid_document}
before do
Airport.delete_all
end
context do
let(:nameable){Factory.create(:airport,
:name_en => 'Name',
:name_ru => 'Имя'
)}
it_behaves_like :Nameable
end
Вобщем то, переменных может быть сколько угодно, это зависит от тестируемого модуля. Теперь добавляем примерно тоже самое в spec/models/city_spec.rb:
require 'models/nameable_spec'
describe City do
it{should be_mongoid_document}
before do
City.delete_all
end
context do
let(:nameable){Factory.create(:city,
:name_en => 'Name',
:name_ru => 'Имя'
)}
it_behaves_like :Nameable
end
Запускаем тест:
Работает. Запускаем несколько тестов:
Тесты вызывают ошибку:
from /Users/undr/.rvm/gems/ruby-1.9.2-p180/gems/rspec-core-2.6.4/lib/rspec/core/shared_example_group.rb:8:in `shared_context'
from /Users/undr/projects/ruby/*******/spec/models/nameable_spec.rb:1:in `<top (required)>'
from /Users/undr/.rvm/gems/ruby-1.9.2-p180/gems/activesupport-3.1.0/lib/active_support/dependencies.rb:234:in `load'
from /Users/undr/.rvm/gems/ruby-1.9.2-p180/gems/activesupport-3.1.0/lib/active_support/dependencies.rb:234:in `block in load'
...
Чтобы избежать этого надо предотвратить повторное определение блока shared_examples_for. Просто этот перед определением блока делайте проверку на его наличие:
shared_examples_for :Nameable do
...
end
end
Таким образом у меня получилось удобно, без лишнего кода, тестировать модули подмешанные к классам.
